Angular为什么需要service
- 组件应该是专注于展示层,所以需要service来获取数据和保存数据。
- 组件之间的通信需要service来协助完成。
众所周知,angular中service采用的是依赖注入,那什么是依赖注入呢?
为什么需要依赖注入
从一个小例子说起
export class Car { public engine: Engine; // 引擎 public tires: Tires; // 轮胎 constructor() { this.engine = new Engine(); this.tires = new Tires(); }}//如果更换了引擎的构造函数,要传入气缸数,构造函数则要跟着改 constructor() { this.engine = new Engine(12); this.tires = new Tires(); }复制代码
上面创建了一个汽车类,但是这个类完全没有健壮性。假如引擎的构造函数改变了,构建引擎的时候需要传一个参数,我们就得去汽车类里面改变new Engine()这个使用。如果仅仅是需要改两个地方可能还能接受,但是如果引擎类还依赖别的零件,这么一层层的依赖关系,其中一个构造函数要发生改变了,可能会导致一连串的改变,会导致写出来的代码完全没有可维护性。轮胎也是如此,不同的汽车需要不同的轮胎,那么像上述这么写就不太灵活,没有通用性可言。
所以这样就需要依赖注入
export class Car { constructor(public engine: Engine, public tires: Tires) { } }let car = new Car(new Engine(), new Tires());复制代码
这样 engine和tire 和car类就是分离的,只要你是传入的引擎和轮胎是满足要求的,那么这个car就是okay的。
class Engine2 { constructor(public cylinders: number) { }}// 如果需要一个12缸的引擎, 这样我们完全不用动car类。let bigCylinders = 12;let car = new Car(new Engine2(bigCylinders), new Tires());复制代码
依赖注入这种模式也为编写测试用例提供了方便,在测试car类的时候,你不必去关系轮胎细节,只要给出一个可用的轮胎就行。
上面解释了依赖注入是什么,以及为什么需要依赖注入。就是一个类从外界接受他所需要的依赖关系,而不是自己去创造它们。但是对于消费者,问题又来了。想要一辆车,就必须得有一个工厂来组装出一个车
import { Engine, Tires, Car } from './car';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(); }}复制代码
这个模式看来起似乎没有问题,但是这只是简化的依赖,类似的引擎工厂类, 轮胎工厂类,相互调用,相互依赖,这会形成一个不可维护的?️
这个时候就需要一个依赖注入框架了。这个框架有一个叫注入器的东西,需要一个Car时, 只需要
let car = injector.get(Car);复制代码
这样消费者也不用去维护生产car的工厂类。并且car类本身也不管轮胎,引擎怎么来的。皆大欢喜。
angular中依赖注入模式
angular中采用的是分层依赖注入
angular的应用程序是一个组件树,每一个组件实例化都有自己的注入器providers。
组件在找service的时候会一直向上冒泡寻找,直到找到根组件AppComponent还没有找到的时候就会报错。
这样设计的好处:
- 便于组件之间的通信。顶层一点的组件可以统一控制多个子组件的对同一个数据的操作。
- 增加复用。可以抽出多个底层组件复用的service写在上层组件中。
angular中service的小知识
- 生成一个module的service。 ng g service test --module=app
src/app/test.service.tsimport { Injectable } from '@angular/core';@Injectable()export class TestService { constructor() { }}复制代码采用 @Injectable()装饰器,这个东西告诉angular这个服务类可能本身注入了依赖, 组件本身是不管服务内部怎么运作。 service是必须通过providers注入。 是可以在服务的构造函数中调用一些业务函数 ,但不是最佳实践。 服务在app内是单例的。