Angular装饰器
@Injectable
如果一个 Service 里面需要依赖其他 Service,需要使用 @Injectable 装饰器进行装饰。为了不给自己找麻烦,最好所有 Service 都加上 @Injectable 装饰器,这是一种良好的编码风格。用 @angular/cli 生成的 Service 会自动在头部加上 @Injectable 装饰器,不需要操心。
1 | //这里我们把http服务注入到GoodsListService里 |
在配置ModuleInjector
时,推荐使用@Injectable()
的 providedIn 属性优于 @NgModule()
的 providers 数组,因为使用 @Injectable()
的 providedIn 时,优化工具可以进行摇树优化,从而删除您的应用程序中未使用的服务,以减小捆绑包尺寸。
@Inject
@Injectable与@Inject之间的关系,就像汽车自动挡和手动挡的区别。
1 | import { HttpClient } from '@angular/common/http'; |
用 @Inject 和用 @Injectable 最终编译出来的代码是不一样的。用 @Inject 生成的代码多了很多东西,如果出现大量这种代码,最终编译出来的文件体积会变大。
- 我们可以自己手动用 @Inject 装饰器来让 TypeScript 编译器保留类型元数据,但是一般来说不需要这么干(也就是说,@Inject 装饰器一般是用不到的,除非你想做一些其他的事情)。
- 保留类型元数据的另一个简便方法是使用 @Injectable 装饰器,@Injectable 并没有什么神奇的作用,它只是告诉 TS 编译器:请生成类型元数据,然后 Angular 在运行时就知道应该注射什么类型的对象了。
- 这是 TypeScript 强加的一个规则,如果不加 @Injectable 装饰器,TS 编译器会把参数类型元数据丢弃。对于 Angular 中的 Service 来说,最好都加上 @Injectable
@Self
@Self 装饰器来提示注射器,不要向上查找,只在组件自身内部查找依赖。
1 | //在组件里添加Self服务引用 |
@Optional
用@Optional 装饰器之后,被装饰的服务就变成可选的了。它会沿着Injector Tree向上查找,如果找到了需要注入的类型,就创建实例。
如果没有找到,就会被赋值为null,不会报错!
1 | // 我们可以把@Self 和@Optional 结合使用 |
这时候不在@Component注入服务,也不会报错了😂😂😂
@SkipSelf
跳过组件自身,然后沿着 Injector Tree 向上查找
1 | // 我们可以把@Self 和@Optional 结合使用 |
这样写的含义是:
- 因为使用了 @SkipSelf 装饰器,所以直接跳过 ChildComponent 组件自身,从 Injector Tree 的父层节点向上进行查找,也就是说,不管 ChildComponent 组件自己有没有配置 UserListService 都不起作用,因为跳过去了;
- 因为使用了 @Optional 装饰器,如果在父层上面找到了指定的类型,那就创建实例;否则,直接设置为 null,不抛异常。