[Angular] Control the dependency lookup with @Host, @Self, @SkipSelf and @Optional
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) {}
}
[Angular] Control the dependency lookup with @Host, @Self, @SkipSelf and @Optional的更多相关文章
- [Angular] Component's dependency injection
An Angular service registered on the NgModule is globally visible on the entire application. Moreove ...
- [Angular Tutorial] 7-XHRs & Dependency Injection
我们受够了在应用中用硬编码的方法嵌入三部电话!现在让我们用Angular内建的叫做$http的服务来从我们的服务器获取更大的数据集吧.我们将会使用Angular的依赖注入来为PhoneListCtrl ...
- [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, ...
- 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 ...
- angular(常识)
我觉得angularjs是前端框架,而jquery只是前端工具,这两个还是没有可比性的. 看知乎上关于jquery和angular的对比http://www.zhihu.com/question/27 ...
- Angular 4+ 修仙之路
Angular 4.x 快速入门 Angular 4 快速入门 涉及 Angular 简介.环境搭建.插件表达式.自定义组件.表单模块.Http 模块等 Angular 4 基础教程 涉及 Angul ...
- Dependency Injection
Inversion of Control - Dependency Injection - Dependency Lookup loose coupling/maintainability/ late ...
- Hosting custom WPF calendar control in AX 2012
原作者: https://community.dynamics.com/ax/b/axilicious/archive/2013/05/20/hosting-custom-wpf-calendar-c ...
- Spring (一) IOC ( Inversion Of Control )
前序 现在小米手机很火就还拿小米手机来举例子,上一篇写的关于SSH框架搭建是从小米手机公司内个整个流程方面来考虑,如何提高效率生产效率,这篇博客主要从公司外部环境说明如何提高生产效率,那么怎么才能提高 ...
随机推荐
- 【python】正则表达式相关
注意:Python3.X 的print要有括号, Python 2.x的不需要 放上学习时写的例子: import re m = re.match(r'(\w+) (\w+)(?P<sign&g ...
- 一个关于Java 多线程问题的知识点
这个程序运行结果会是什么? public class Main {static class ListAdd { private static List list = new ArrayList(); ...
- Selenium2+python自动化37-爬页面源码(page_source)【转载】
前言 有时候通过元素的属性的查找页面上的某个元素,可能不太好找,这时候可以从源码中爬出想要的信息.selenium的page_source方法可以获取到页面源码. selenium的page_sour ...
- python带cookie提交表单自动登录
import urllib import urllib2 import cookielib login_url = "xxxxxxxxxxxxx" cj = cookielib.C ...
- debug 英文翻译
declaration of 'int a' shadows a parameter :函数参数里,已经有这两个名称的变量了,指定义了同名的参数,造成了隐藏. expected primary-exp ...
- HYSBZ - 2038 小Z的袜子 (莫队算法)
A1206. 小Z的袜子 时间限制:1.0s 内存限制:512.0MB 总提交次数:744 AC次数:210 平均分:44.44 将本题分享到: 查看未格式化的试题 ...
- Linux命令之kill
kill [-s signal | -p] [ --] pid… kill –l [signal] 终止指定进程.命令kill将指定的信号发送到指定的进程或进程组.如果没有指定信号,则发送SIGTER ...
- 数据库的语言——SQL
DBMS 是一种系统软件,我们要与它交互的时候就必须使用某种语言,在数据库发展初期每一种DBMS 都有自己的特有的语言,不过逐渐的SQL 成为了所有DBMS 都支持的主流语言.SQL 是专为数据库而建 ...
- [BZOJ 3233] 找硬币
Link: BZOJ 3233 传送门 Solution: 在本蒟蒻看来算是一道比较神的$dp$了 一开始转移方程都没看出来…… 首先,如果确定了最大面值,是能推出其他面值的所有可能值的 从而发现最大 ...
- pythonGUI菜单栏和弹出菜单
菜单栏代码: from tkinter import * root = Tk() menubar = Menu(root) def callback(): pass filemenu = Menu(m ...