【背景】
最近在学习Angular,迫不及待想跟学习到的知识跟大家分享。
【内容】
什么是依赖注入?
依赖注入是“控制反转”(将实例化这个类的控制权交给外部,从而实现类与组件的解耦)的一体两面。控制反转是目的,依赖注入是手段。是不是不太明白,说得直白一点就是在程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。
怎么用?
我们在组件需要某个服务的实例时,不需要手动创建这个实例,只需要在构造函数的参数中指定这个实例的变量,以及这个实例的类,然后angular会根据这个类的名字找到providers属性中指定的同名的provide,再找到它对应的useclass,最终自动创建这个服务的实例。
一、注入器
在组件中的constructor中:
constructor(private productService: ProductService){}这段代码的意思是,这个组件创建了一个productService,而这个productService是依赖ProductService的,这里的ProductService只是一个token。
二、提供器
通常提供器定义在应用级,及app.module.ts中,供所有组件或服务使用,当然也可以定义在某一个组件中,只供这一个组件使用。
// 两个属性同名 providers: [ProductService] // 完整写法 providers: [{provide: ProductService,useClass: ProductService}] // 不同名写法 providers: [{provide: ProductService,useClass: AnotherProductService}] // 用工厂方式创建这个实例 providers: [{provide: ProductService,useFactory: ()=>{...}}]
这段代码中的provide声明的就是我们刚刚在注入器中提过的token,就是说这两个token是一一对应的,Angular会到提供器中找到和注入器相同的token。代码中的useClass是实例化ProductService类,即帮助我们new了一个类出来,除了useClass外,比较常用的还有useFactory,使用工厂模式实例化一个类,还有useValue。这时候我们在组件中就可以直接使用ProductService类中的方法了。
好处是什么?
在Angular中使用依赖注入,可以帮助我们实现松耦合,实现组件的可重用性。
如果我们有个服务product.service.ts,其中export了一个ProductService类,类中有一个getProducts方法。如果不使用依赖注入,假设我们需要在product组件中使用这个服务时就会new一个ProductService类,但如果这个组件被用到了另一个地方,需要的服务改变了,我们就不得不更改组件中的内容,这样的组件不能说是可复用的。用了依赖注入,这样的情况就不再会发生了。
如果现在product组件用到了另一个地方需要另一个服务,我们命名为OtherProductService,有了依赖注入之后我们就不必更改组件的内容,只需要更改app.module.ts中的提供器。
@NgModule({ provide: ProductService,useClass: OtherProductService })
这段代码中,token并没有改变,可是实例化的类变了。
提供器的作用域原则
1.提供器声明在模块时是对所有组件是可见的,所有组件都可以注入。
2.当一个提供器声明在组件时,只对他声明的组件和子组件可见,其他组件不可注入。
3.当声明在模块的提供器和组件的提供器具有相同的token时,声明在组件的提供器会覆盖模块的提供。
4.服务提供器优先声明在模块中,只有服务必须在某个组件可见,对其他组件不可见时才声明在组件中
当组件在构造函数中说明自己想要依赖一个类时,Angular首先会在这个组件自身找看有没有这个提供器,如果没有就去这个组件的父组件中找,如果也没有就去应用级(app.modules.ts)中去找。找到后,就会按照提供器可说明的为组件注入它想要的。【感受】
基础知识点先一点点总结着,期待破茧成蝶的那一天。