问题
From what I understand, we use services in the case of inter and intra components communication where we hide multiple or complex data structures. Is it true we only use services in the case of persistent data structure? So what are cases we should not use services?
回答1:
I Would beg to differ with the statement you made.
From what I understand, we use services in the case of inter and intra components communication where we hide multiple or complex data structures.
Instead of answering when we should not use angular service? I would answer what, why and when to use services?
Services
A Service is a class with a specific purpose, and In Angular, we use services mainly for three purposes.
1.To Implement any Business Logic that is independent of any Component
.
Example
Assume you want to calculate the age from DOB, Now you provide the year
and The logic can give you age you would not need an HTML view to do that
,it is component Independent
2. Access to Shared Data.
When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should use a shared service.
You could either use RXJS BehaviorSubject or Subject for cross component communication.
The advantage of using BehaviorSubject
or a Subject
for cross-component interaction over plain getters
and setters
is you don't need to manually trigger a method to fetch latest data. Whenever the data is changed all the components where service is injected are automatically notified.
What is the difference between Subject and BehaviorSubject???
3. External Interactions
1.Accessing REST Web Services Using Http
-----------------------------------------------------------------------------------------------------------------------------------
Why use Services in Angular
Angular distinguishes components from services in order to increase modularity and reusability.
and It's Good Practice to Delegate complex component logic to services
From Angular Style Guide
Do limit logic in a component to only that required for the view. All other logic should be delegated to services.Do move reusable logic to services and keep components simple and focused on their intended purpose.
Why? Logic may be reused by multiple components when placed within a service and exposed via a function.
Why? Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.
Why? Removes dependencies and hides implementation details from the component.
Why? Keeps the component slim, trim, and focused.
Usage of Services In Angular also ensures that you are not violating DRY and SRP principles of software development.
Providing Services
FROM Angular Docs
Should you provide a service with an
@Injectable
decorator, in an@NgModule
, or within an@Component
? The choices lead to differences in the final bundle size, service scope, and service lifetime.When you register providers in the
@Injectable
decorator of the service itself, optimization tools such as those used by the CLI's production builds can perform tree shaking, which removes services that aren't used by your app. Tree shaking results in smaller bundle sizes.Angular module providers
(@NgModule.providers)
are registered with the application's root injector. Angular can inject the corresponding services in any class it creates. Once created, a service instance lives for the life of the app and Angular injects this one service instance in every class that needs it.A component's providers
(@Component.providers)
are registered with each component instance's own injector.Angular can only inject the corresponding services in that component instance or one of its descendant component instances. Angular cannot inject the same service instance anywhere else.
Note that a component-provided service may have a limited lifetime. Each new instance of the component gets its own instance of the service and, when the component instance is destroyed, so is that service instance
TLDR
if we want an instance of a dependency to be shared globally and share state
across the application we configure it on the NgModule
.
If we want a separate instance of a dependency to be shared across each instance of a component and it’s children we configure it on the components providers
property.
To get a Clear Picture Go through Angular's Hierarchical Dependency Injection system
Well, it's recommended to Always register application-wide services with the root AppModule which makes a service singleton(it will live as long as our application lives) but it entirely depends upon the use case.
If the sole purpose of the service is to share data between child’s components and to provide a couple of helper’s methods.
Register it with component providers and make it a non-singleton service.
The benefit is that when Angular destroys the component, Angular will also destroy the service and release the memory that is occupied by it.@Credit
FAQ
回答2:
Where did you hear that is bad practice? Using service for getting data from API by HTTPRequest or sharing data between components is good practice, check my example here: Share methods between two components in same page Angular
Important thing that you have to remember is that Services are an application-wide singleton. Therfore put services only into CoreModule, and import CoreModule only once in AppModule, nowhere else. You don't want each module to have its own separate instance. (More about the difference between CoreModule and SharedModule: Angular2: CoreModule vs SharedModule)
Yet there is a real danger of that happening if the SharedModule provides the Service. It might be required for example if you are using Service for some reusable component, eg. in directive which is actually in SharedModule. Then you have to use forRoot()
whilst you importing ShareModule, example:
import { NgModule, ModuleWithProviders } from '@angular/core';
import { MyDirective } from './my.directive';
import { SomeService } from './some.service';
@NgModule({
declarations: [
MyDirective
],
exports: [
MyDirective
]
})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [ SomeService ]
};
}
}
Some other module:
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
SharedModule.forRoot()
]
})
export class SomeModule {}
I hope it helps :)
来源:https://stackoverflow.com/questions/50625913/when-we-should-not-use-angular-service