发表于: 2017-05-12 22:35:28
1 976
今天完成的事情
- 1. 依赖注入看了半章
- 2. 后面半章没看懂其实是因为好多参数,加上依赖注入本身理解的就不透彻,于是就看不了后面了
- 下午就卖了几箱樱桃,,
明天计划的事情
1. 依赖注入先放一放
2. 官网有个小demo跟着做一做,估计收获比这个大
遇到的问题
依赖注入这么多参数真的用得到吗?
收获
Angular 的依赖注入系统能够即时地创建和交付所依赖的服务。
它是一种编程模式,可以让类从外部源中获得它的依赖,而不必亲自创建它们。
怎么说,抄官方一个例子来讲一下:
src/app/car/car.ts
export class Car {public engine: Engine;public tires: Tires;public description = 'No DI';constructor() {this.engine = new Engine();this.tires = new Tires();}// Method using the engine and tiresdrive() {return `${this.description} car with ` +`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;}}
上面的例子在执行起来是没有任何问题的,那么问题在哪里?
首先,来看一Car的创建过程,新建两个变量,然后实例化两个类,并赋值给刚才的变量,之后调用,输出结果。
这样执行当然没有问题。下面假设一种情况,Engine()
需要增加一个参数,变成类似Engine(value: string)
,此时除了改Engine()
之外,还要更改Car
,当项目足够大之后可能根本想不起来都在哪里使用的Engine()
,这样使得维护变得艰难。
除此之外,如果Car
不需要这个Engine()
,而是需要一个Engine2()
,那我们是不是要通通改一遍Car
这是很恐怖的一件事情。
其实我们只需要简单的改一个Car
,将其的构造函数更改为:cnstructor(public engine: Engine, public Tires) {}
这样我们在需要一个Car
的时候只需要:let car = new Car(new Engine(), new Tires());
如此我们就可以轻松的选购各种的Engine()
和Tires()
好,一切显得那么美好,but,有选择艰难症的人就麻烦了,他们希望不用选择就可以得到一个默认的较好的配置,那么怎么办:
(下面这个方法不推荐)
src/app/car/car-factory.ts
import { Engine, Tires, Car } from './car';// BAD pattern!export class CarFactory {createCar() {let car = new Car(this.createEngine(), this.createTires());car.description = 'Factory';return car;}createEngine() {return new Engine();}createTires() {return new Tires();}}
好,这里是默认配置,需要更改以后直接更改这个就好了。
那么,作为工程师的我们又得辛苦了,这个工厂的维护就交给我们了,好烦。有没有更好的办法?幸好Angular提供了一个叫注入器的东西,这一切交给注入器就好了:let car = injector.get(Car);
哇,好简单,一键生成,完美。
那么,我们是怎么做的呢?
- 首先,定义一个服务,并将这个服务对外暴露出去,与平常不同的是,我们需要用到
@injectable
这个装饰类,这个装饰类的作用是:使这个服务在其他组件中是可被导入的。允许我粘一波代码:
src/app/heroes/hero.service.ts
import { Injectable } from '@angular/core';import { HEROES } from './mock-heroes';@Injectable()export class HeroService {getHeroes() { return HEROES; }}
- 接着我们需要配置注入器,其实是不用配置的,在新建项目的时候Angular已经帮我们配置好了。(一个项目总不可能一个服务都没有吧。。。)
- 还需要在
NgModule
中注册提供商:
src/app/app.module.ts (excerpt)
providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }],
这里没有直接使用providers: [HeroService]
,因为providers: [HeroService]
是简写的方式,如果需要配置参数,必须写成上面的形式,参数有许多。
注册到AppModule
里面是由于这个服务需要在在整个应用中被访问。
4. 要使用这个服务还需要在被使用的组件中导入它,
import { HeroService } from './hero.service';export class HeroListComponent {heroes: Hero[];constructor(heroService: HeroService) {this.heroes = heroService.getHeroes();}}
这样我们就可以使用了。
如果想只在这个组件以及它的子组件中使用这个服务,我们值需要在这个组件的服务提供商中导入就可以,可以使用providers: [HeroService]
。
5. 接着就可以这样了:let car = injector.get(Car);
ok,这是今天重新理解的依赖注入,下面的方法依然懵,搞不懂。
评论