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. Oracle rman 各种恢复

    --恢复整个数据库run {shutdown immediate;startup mount;restore database;recover database;alter database open ...

  2. word-wrap

    平时的网页制作中碰到过这样的情况,比如说在blog中制作了一个完美而且又靓丽的评论布局,让你的用户浏览网页是可以给你添加评论,但当有人发布了一个原始网址或者其它超长的文本时,你此时的布局就被他们给彻底 ...

  3. magento 报错及解决方法

    在后台安装主题包时安装出错,重新进入后台进不去,前台也进不去,提示“Service Temporarily Unavailable” 删除根目录下的maintenance.flag文件即可.

  4. django web 自定义通用权限控制

    需求:web系统有包含以下5个url,分别对于不同资源: 1.stu/add_stu/ 2.stu/upload_homework/ 3.stu/query_homework/ 4.stu/add_r ...

  5. 利用navigator对象判断设备类型

    function getTerminalType() { //获取navigator对象 var o = navigator.userAgent, t = ""; if (/\bi ...

  6. hihocoder Popular Products(STL)

    Popular Products 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given N lists of customer purchase, your tas ...

  7. 11、Django实战第11天:templates模板继承

    Django模板的继承,它首先定义一个整体的框架(父类),然后动态的部分(子类)只需要重写自己本身的代码就可以了. 1.在templates目录下创建base.html 2.把org-list.htm ...

  8. CSS选择符——分门别类

    CSS选择符--分门别类 有时候,老是会对一些CSS选择器模模糊糊,傻傻分不清.今天花了点时间整理了一下,感觉世界清静了不少. 用XMIND做出了思维导图: 主要有11中选择器:元素.类ID.后代.子 ...

  9. 简化的INSERT语句

    INSERT语句中也并不需要我们指定表中的所有列,比如在插入数据的时候某些字段没有值,我们可以忽略这些字段.下面我们插入一条没有备注信息的数据: INSERT INTO T_Person(FAge,F ...

  10. 一年的天数 Exercise06_16

    /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:一年的天数 * */ public class Exercise06_16 { public static void main ...