服务:
组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。
服务
为什么需要服务?
因为:组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。
这个新的服务导入了 Angular 的Injectable 符号,并且给这个服务类添加了 @Injectable() 装饰器
可以从任何地方获取数据:Web 服务、本地存储(LocalStorage)或一个模拟的数据源。
好处:从组件中移除数据访问逻辑,意味着将来任何时候你都可以改变目前的实现方式,而不用改动任何组件。
1.在要求 Angular 把HeroService注入到?HeroesComponent之前,你必须先把这个服务提供给依赖注入系统。通过注册提供商来做到这一点。提供商用来创建和交付服务,在这个例子中,它会对HeroService类进行实例化,以提供该服务,需要确保HeroService已经作为该服务的提供商进行过注册。 你要用一个注入器注册它。注入器就是一个对象,负责在需要时选取和注入该提供商。默认情况下,Angular CLI 命令ng generate service会通过给@Injectable装饰器添加元数据的形式,为该服务把提供商注册到根注入器上。如果你看看HeroService紧前面的@Injectable()语句定义,就会发现providedIn元数据的值是 'root',当你在顶层提供该服务时,Angular 就会为HeroService创建一个单一的、共享的实例,并把它注入到任何想要它的类上。 在@Injectable元数据中注册该提供商,还能让 Angular 可以通过移除那些完全没有用过的服务,来进行优化。
(这段话的意思是:你如果想在组件中使用服务,你必须先给服务把提供商注入到跟注入器上,怎么才能把提供商注入到根注入器上?通过给 @Injectable 装饰器添加元数据的形式,为该服务把提供商注册到根注入器上,@Injectable()装饰器的元数据值是root,providedIn就是服务提供商)
2.依赖注入
依赖注入(你需要在组件中注入依赖,即在组件的构造函数中注入依赖,而不是自己使用 new 来创建自己的 HeroService 实例。一个是框架帮你创建对象,一个是你手动创建对象,一个有利于代码解耦,一个不利于
)
提供商的作用域
当你把服务提供商添加到应用的根注入器中时,它就在整个应用程序中可用
providedIn 与 NgModule
也可以规定某个服务只有在特定的 @NgModule 中提供。比如,如果你你希望只有当消费方导入了你创建的 UserModule 时才让 UserService 在应用中生效,那就可以指定该服务要在该模块中提供:
src/app/user.service.ts:
import { Injectable } from '@angular/core';
import { UserModule } from './user.module';
@Injectable({
providedIn: UserModule,
})
export class UserService {
}
上面的例子展示的就是在模块中提供服务的首选方式。之所以推荐该方式,是因为当没有人注入它时,该服务就可以被摇树优化掉。如果没办法指定哪个模块该提供这个服务,你也可以在那个模块中为该服务声明一个提供商:
src/app/user.module.ts
import { NgModule } from '@angular/core';
import { UserService } from './user.service';
@NgModule({
providers: [UserService],
})
export class UserModule {
}
注意:如果需要,可以在不同的层次上注册提供商 —— 在 HeroesComponent 中、在 AppComponent 中,或在 AppModule 中。 比如,可以通过附加 --module=app 参数来告诉 CLI 要自动在模块级提供该服务。