Joe*_*ash 2 service dependency-injection angular
我目前正在其主要网站上关注Angular教程,但对其中的概念之一感到困难。它在指的是什么服务和什么是提供者的方式上感觉很松散,我无法确定它是一个还是另一个。该链接将您带到本教程的问题部分。
https://angular.io/tutorial/toh-pt4#injectable-services
据我所知,服务用于将数据提供给组件。组件通过将服务注入到服务中来访问服务。但是,注入器本身就是存在的东西,在注入服务之前,必须使服务适用于该服务。
但是,我正在阅读的指南在指的是什么是服务和什么是提供者方面感觉很松散。起初,我认为整个Hero.Service.ts都是Service。然后,它说@Injectable将类标记为Service。好的,是的,这就是组件的工作方式,装饰器指定它是什么。但随后指南说,
“ HeroService类将提供可注射的服务”
等待,所以HeroService不是服务,它提供了服务对象?请记住,稍后将出现“将提供可注射的服务”一词。
该指南详细介绍了服务如何检索组件的数据,然后介绍了如何通过提供程序将服务引入依赖项注入程序。
这是麻烦。它说提供者创建或交付服务,在这种情况下实例化HeroService。然后它说HeroService将成为HeroService的提供者。重复一遍,以下两行将HeroService称为服务
暗示:“在Angular可以将HeroService注入HeroesComponent之前,必须使HeroService可用于依赖项注入系统”
再次隐式地表示:“您可以通过注册提供程序来执行此操作。提供程序可以创建或交付服务;在这种情况下,它会实例化HeroService类以提供服务。”
在教程标题创建HeroService之前,“他们应该专注于呈现数据并将数据访问权委派给服务...在本教程中,您将创建一个HeroService,所有应用程序类都可以使用它来获得英雄。” 注意:英雄是数据
但是,然后他们说HeroService已注册为提供者?“现在,您需要确保HeroService已注册为该服务的提供者。”如果HeroService是提供者,则“此服务”指的是什么?
现在,请记住“ HeroService类将提供可注射的服务”这一行
因此,在本教程的两行中,将HeroService即服务称为服务,另外两行则将其称为Provider。除非在后一种情况下,否则他们以严格口语化的方式使用“提供”或“服务”一词,而实际上并非指提供者和服务。
它在指的是什么服务和什么是提供者的方式上感觉很松散,我无法确定它是一个还是另一个。
A服务是一个JavaScript 对象存在于您的应用程序,并且提供者是这样,你访问该对象。两者不是一回事,但是它们一起使您可以从其他地方访问您的服务。没有提供者,您将无法获得服务,而提供者需要提供一些东西。
服务只是一个用来描述对象实例的术语(通常是TypeScript类)。之所以将它们称为“服务”,是因为该术语通常在依赖项注入中用于描述执行单个目的的共享库。
“ HeroService类将提供可注射的服务”
这里的“ 提供 ”一词是指语法中的动词。不应将其与Angular用于在提供程序列表中定义条目的TypeScript类型的提供程序混淆。
编写以上句子的更好方法:
“ HeroService类将声明可注入服务”
我同意您所说的令人困惑。因此,我将仅说明工作原理。
单个提供程序是一个实现Provider接口(实际上是多个接口)的JavaScript对象,但我的观点是,它是一个告诉Angular如何将令牌与value关联的对象。
只有A NgModule可以在编译时定义提供程序。我们经常这样做:
@NgModule({
providers: [HeroService]
})
Run Code Online (Sandbox Code Playgroud)
现在,请记住上面我曾说过提供者是一个JavaScript对象,但是在NgModule示例中我们没有定义对象。我们只是使用HeroService从技术上讲是构造函数。
这是为了使程序员更容易。在编译时角将看看HeroService,看看有什么元说,关于它,它会自动生成提供对象。
该元数据是通过执行以下操作创建的。
@Injectable()
export class HeroService {}
Run Code Online (Sandbox Code Playgroud)
该@Injectable装饰增加了隐藏的元数据描述了如何创建一个HeroService实例。
我们可以通过自己定义提供者对象来做同样的事情,如果我们使用提供者对象来做,则该服务不需要@Injectable装饰器,因为我们是自己创建的。
@NgModule({
providers: [{provide: HeroService, useValue: new HeroService()}]
})
Run Code Online (Sandbox Code Playgroud)
现在我们可以解释为什么他们说“ HeroService类将提供可注射的服务”。这是因为HeroService使用@Injectable修饰符来声明服务的提供程序。
Angular为您做了很多工作。在编写组件时,您想注入HeroService以便可以使用它。您要做的只是以下内容。
@Component({....})
export class AppComponent {
constructor(heroService: HeroService) {
// ^^^ this is the provider token
}
}
Run Code Online (Sandbox Code Playgroud)
上面的方法起作用是因为Angular可以推断出构造函数需要哪些提供程序。它查看第一个参数,并看到类型为HeroService。我们将其称为可注入令牌,Angular可以在提供程序中进行搜索以查找其所在的位置provide: HeroService。然后,它使用该提供程序获取值并将其传递给构造函数。
我们可以通过执行以下操作来打破依赖注入。
@Component({....})
export class AppComponent {
constructor(heroService: any) {
// ^^^ this is an unknown provider
}
}
Run Code Online (Sandbox Code Playgroud)
角再也不能推断该令牌的供应商。它不知道所声明的许多提供程序中的哪个是程序员想要使用的提供程序。
我们可以声明我们真正想要的提供者令牌。
@Component({....})
export class AppComponent {
constructor(@Inject(HeroService) heroService: any) {
// ^^^ we declare the token manually
}
}
Run Code Online (Sandbox Code Playgroud)
当Angular需要帮助时,我们使用@Inject装饰器手动声明应使用哪个提供者令牌。
在Angular 6中,引入了一项新功能,使您可以在根模块中将Service声明为提供程序。这是注射剂的“ providedIn”选项。
@Injectable({ providedIn: 'root' })
export class HeroService {}
Run Code Online (Sandbox Code Playgroud)
上面我说过,这样@Injectable可以更轻松地将类添加到provider数组中NgModule。好吧,这providerIn又向前迈进了一步,现在为您直接将其添加到模块中。
这些事情可能会造成混淆,因为它们隐藏了依赖项注入系统正在执行的基础工作。它使更多功能看起来像魔术,而不是说明它们在做什么。
| 归档时间: |
|
| 查看次数: |
684 次 |
| 最近记录: |