

angular 依赖注入 - SegmentFault 思否
source link: https://segmentfault.com/a/1190000040920582
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

angular 依赖注入
问题起因是因为在GriderService中忘记给根模块提供注入。
即没有写
@Injectable({ providedIn: 'root' })
当时想着,能不能单纯在组件中使用provide GriderService使这个组件正常用service提供的服务.就像下面这样:
providers: [ { provide: GriderService } ]
但这样还不行。
因为GriderService的函数中同样需要依赖注入HttpClient,如下
constructor(protected httpClient: HttpClient) { }
所以,手动注入GriderService需要先手动注入HttpClient。
所以我尝试着手动注入了HttpClient。并且如果new一个HttpClient的话,需要先new一个HttpHandler,这是Httpclient的构造函数所需要的。或许我应该这么做:
let httpHandler = new HttpHandler(); let httpClient = new HttpClient(httpHandler);
但是,实际上HttpHandler是抽象类,并不能被实例化。
最后也没查到什么可行性的代码。我们应该使用依赖注入。DI是 Angular 中的一个基本概念,也是使该框架如此有用的原因之一。
@Injectable() 装饰器标识服务类。该 providedIn 属性配置指定的 ModuleInjector,这里的 root 会把让该服务在 root ModuleInjector 上可用
用 @Injectable() 的 providedIn 属性优于 @NgModule() 的 providers 数组,不仅在于它方便快捷,还因为使用 @Injectable() 的 providedIn 时,优化工具可以进行摇树优化(Tree Shaking)简单来说 经过Tree Shaking,不该留在代码中的多余代码,则会被摇掉。
root 实际上是 AppModule 的别名,表示根模块,我们因此不需要额外导入 AppModule,所有的模块原则上都属于根模块的子模块,所以所有的子模块都可以无条件的使用root根模块上的资源
关于注射器
在 root ModuleInjector 之上还有两个注入器,一个是额外的 ModuleInjector,一个是 NullInjector()
为了理解这张图,先大致了解一下从angular启动。
angular启动
每一个 Angular 应用都以 main.ts 文件作为起点。(main.cs目前位于项目的src文件夹下,与app文件夹是同一级)
main.cs中最关键的是这两行代码:
1.platformBrowserDynamic() 方法创建一个由 PlatformModule 配置的注入器,简单来说就是浏览器平台的工厂函数,执行会返回浏览器平台的实例。
2.bootstrapModule() 方法会创建一个由 AppModule 配置的注入器作为平台注入器的子注入器。也就是 root ModuleInjector
3.同时bootstrapModule启动app文件夹下的AppModule后,Angular 会去检查模块 AppModule 的 bootstrap 属性,该模块是用来启动程序的:
@NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule {}
依赖注入服务流程
大致理解了启动流程之后,我们再结合刚才那张图来看就很好理解了。
1.platformBrowserDynamic创建一个由 PlatformModule 配置的注入器Modele Injector。该注入器包含特定平台的依赖项
2.使用bootstrapModule方法,创建root ModeleInjector。
3.root ModeleInjector启动之后。若某个service可以给root提供服务,即
该service依赖注入root,root模块就可以使用该service提供的服务。
图例
至于最顶层的NullInjector(),它是树的顶部。如果你在树中向上走了很远,以至于要在 NullInjector() 中寻找服务,那么除非使用 @Optional(),否则将收到错误消息,因为最终所有东西都将以 NullInjector() 结束并返回错误。
总结:DI增加了angular应用程序的灵活性和模块化,它可以使得我们这样方便地使用
constructor(private http: HttpClient)
假如没有Angular DI机制,我们必须手动提供HttpClient来创建我们自己的服务。
Recommend
-
28
关注 Weex 开发进展的同学,可能会知道 Weex 前段时间发布了 v0.18.0 版本(release note),其中包含了一个叫 <recycle-list> 的组件,它是一个带有回收复用功能的列表容器,据说是有史以来最特别的组件,...
-
69
Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 Java10的新特性 Java11的新特性 序 本文主要讲述一下Java10的新特性 特性列表 286: Local-Variable Type Inference(重...
-
55
-
35
-
46
-
32
-
7
我们在对表单进行验证时,有时需要对多个字段同时进行验证,对不同字段的值进行比较,并针对它们的组合判断是否验证通过,在这种情况下使用对单一字段进行验证的验证器难以实现,这个时候就需要用到组验证器,在官方文档也叫跨字段交叉验证器。组验证器...
-
2
作为“为大型前端项目”而设计的前端框架,Angular 其实有许多值得参考和学习的设计,本系列主要用于研究这些设计和功能的实现原理。本文主要围绕 Angular 中的最大特点——依赖注入,介绍 Angular 依赖注入在体系在应用引导过程中的的设计和实现。
-
5
作为“为大型前端项目”而设计的前端框架,Angular 其实有许多值得参考和学习的设计,本系列主要用于研究这些设计和功能的实现原理。本文主要围绕 Angular 中的最大特点——依赖注入,介绍 Angular 中多级依赖注入的设计。 上一篇我们介绍了 Angular 中的
-
6
摘要:介绍了Angular中依赖注入是如何查找依赖,如何配置提供商,如何用限定和过滤作用的装饰器拿到想要的实例,进一步通过N个案例分析如何结合依赖注入的知识点来解决开发编程中会遇到的问题。本文分享自华为云社区《
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK