Very differently to AngularJS (v1.x), Angular now has a hierarchical dependency injector. That allows to specify service definitions as well as the service lifetime at various levels in our application. Whenever a service is requested, Angular will walk up the component tree and search for a matching definition. While in most cases that's perfectly fine, often you may want to take control over the dependency lookup. In this lesson we will learn how, by applying"@Host, @Self()@SkipSelf() and @Optional().

@Optional:

When using @Optional, it set logger to null if the LoggerService is not provided instead of error out.

export class PersonComponent implements OnInit {
constructor(
@Optional()
public logger: LoggerService
) {} ngOnInit() {} doLog() {
if (this.logger) {
this.logger.log('Message from PersonComponent');
} else {
console.log('sorry, no logger available');
}
}
}

@SkipSelf:

If child component and parent component both using the same provider and we want to skip using child component's provider instead using parent's provider.

// Child
@Component({
selector: 'app-person',
template: `
<div style="border:1px;">
<p *ngIf="logger === null">I don't have a logger</p>
<button (click)="doLog()">write log</button>
</div>
`
providers: [
{
provide: LoggerService,
useFactory: loggerFactory('PersonComponent')
}
]
})
export class PersonComponent implements OnInit {
constructor(
@SkipSelf()
@Optional()
public logger: LoggerService
) {} ngOnInit() {} doLog() {
if (this.logger) {
this.logger.log('Message from PersonComponent');
} else {
console.log('sorry, no logger available');
}
}
}
// parent

@Component({
selector: 'app-root',
template: `
<h1>Angular Services</h1>
<app-person></app-person>
`,
providers: [
{
provide: LoggerService,
useFactory: loggerFactory('AppComponent')
}
]
})
export class AppComponent {}

SO in the end 'AppComponent ...' log message will appear in the console.

@Self():

Only using the provider for its own component.

@Component({
selector: 'app-person',
template: `
<div style="border:1px;">
<p *ngIf="logger === null">I don't have a logger</p>
<button (click)="doLog()">write log</button>
</div>
`
// providers: [
// {
// provide: LoggerService,
// useFactory: loggerFactory('PersonComponent')
// }
// ]
})
export class PersonComponent implements OnInit {
constructor(
@Self()
@Optional()

public logger: LoggerService
) {} ngOnInit() {} doLog() {
if (this.logger) {
this.logger.log('Message from PersonComponent');
} else {
console.log('sorry, no logger available');
}
}
}

So if PersonComponent has provider defined, it will use its own provider and will not continue searching parent component.

Often @Self can use togerther with @Optional, so if the provider is not defined, then set it to null.

@Host:

When we have directive, we might need to use @Host.

@Component({
selector: 'my-comp',
...
providers: [
MyService // Must have, other directive cannot find it, throw error.
]
})
<my-comp highlighted />
@Directive({
selector: 'highlighted'
})
export class Hightlighted {
// Use the provide inject directly into the host component
constructor (@Host private myService: MyService) {}
}

Because we cannot ensure that host element must have the Injection, if not, Angular will throw error, to prevent that, @Host normally work with @Optional together.

@Directive({
selector: 'highlighted'
})
export class Hightlighted {
// Use the provide inject directly into the host component
constructor (@Optional @Host private myService: MyService) {}
}

Lesson

[Angular] Control the dependency lookup with @Host, @Self, @SkipSelf and @Optional的更多相关文章

  1. [Angular] Component's dependency injection

    An Angular service registered on the NgModule is globally visible on the entire application. Moreove ...

  2. [Angular Tutorial] 7-XHRs & Dependency Injection

    我们受够了在应用中用硬编码的方法嵌入三部电话!现在让我们用Angular内建的叫做$http的服务来从我们的服务器获取更大的数据集吧.我们将会使用Angular的依赖注入来为PhoneListCtrl ...

  3. [AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor

    The upload class will be used in the service layer. Notice it has a constructor for file attribute, ...

  4. How to achieve dialog with lookup control

    How to create a dialog with the lookup as a control, the other control SalesId ItemId lookup is the ...

  5. angular(常识)

    我觉得angularjs是前端框架,而jquery只是前端工具,这两个还是没有可比性的. 看知乎上关于jquery和angular的对比http://www.zhihu.com/question/27 ...

  6. Angular 4+ 修仙之路

    Angular 4.x 快速入门 Angular 4 快速入门 涉及 Angular 简介.环境搭建.插件表达式.自定义组件.表单模块.Http 模块等 Angular 4 基础教程 涉及 Angul ...

  7. Dependency Injection

    Inversion of Control - Dependency Injection - Dependency Lookup loose coupling/maintainability/ late ...

  8. Hosting custom WPF calendar control in AX 2012

    原作者: https://community.dynamics.com/ax/b/axilicious/archive/2013/05/20/hosting-custom-wpf-calendar-c ...

  9. Spring (一) IOC ( Inversion Of Control )

    前序 现在小米手机很火就还拿小米手机来举例子,上一篇写的关于SSH框架搭建是从小米手机公司内个整个流程方面来考虑,如何提高效率生产效率,这篇博客主要从公司外部环境说明如何提高生产效率,那么怎么才能提高 ...

随机推荐

  1. css3带你实现酷炫效果

    css3 私有前缀 -webkit- chrome/safari等webkit内核浏览器 -moz- firfox -o- opera -ms- IE css3 盒子模型 box-sizing 值co ...

  2. [转]C++ 指针和引用

    转自http://www.cnblogs.com/tangxiaobo199181/ 作者:算法生活 微信公众号:算法生活 出处:http://www.cnblogs.com/tangxiaobo19 ...

  3. Selenium2+python自动化73-定位的坑:class属性有空格【转载】

    前言 有些class属性中间有空格,如果直接复制过来定位是会报错的InvalidSelectorException: Message: The given selector u-label f-dn ...

  4. k8s通过configmap管理应用配置信息

    Secret 可以为 Pod 提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap. ConfigMap 的创建和使用方式与 Secret 非常类 ...

  5. python中的enumerate使用

    enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等 一般情况下对一个列表或数组既要遍历索引又要遍历元素时, ...

  6. yii2中判断数据表是否存在数据库中(原创)

    分为两步: 第一步,找出数据库中所有表名,表名得到的是二维数组. 第二步,判断表名是否存在二维数组中 下面就贴我的代码咯. $table_name =‘table’; $juge = $handle- ...

  7. (13)python 正则表达式

    匹配单个字符 f. o    f和o之间是任意字符   例如:fbo123 .. 任意两个字符 \.用来匹配. 边界匹配 the     表示包含the的任何字符串 ^from 表示以from开头的所 ...

  8. (1)Python 安装使用IDLE

    安装 官网 https://www.python.org/ Windows x86 web-based installer 在线安装 Windows x86 executable installer ...

  9. hdu6138(后缀数组)

    hdu6138 题意 给出若干个字符串,每次查询两个字符串,求两个字符串的公共子串且在给出的某一个字符串中作为前缀的最大长度. 分析 求公共子串:后缀数组 判断前缀:字典树 求完后缀数组,遍历下 \( ...

  10. 【费马小定理】HDU4704-Sum

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...