[Angular] Advanced DI
In this post, we are going to see how to solve one design pattern challenge.
The challenge is what we a simplest way to find out the children elements which belongs to Animals, which belongs to Materials inside the container component.
<app-animals>
<cat></cat>
<dog></dog>
<rock></rock>
<fox></fox>
<viking></viking>
</app-animals>
As we can see that:
Animals are <cat>, <dog>, <fox>, <viking>.
Material is <rock>.
1. First way we might use is Tamplate Ref:
<cat #item></cat>
<fox #item></fox>
// #item Ref
It will work, but the problem for this solution is that, the container should know what children it has. Also the chance that I might mis-mark the component.
2. We can use 'directive' + {read: ElementRef}:
animal.directive.ts:
import { Directive } from '@angular/core';
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[animal]'
})
export class AnimalDirective {}
<cat animal></cat>
<dog animal></dog>
@ContentChildren(AnimalDirective, {read: ElementRef}) directiveElementsQL: QueryList<ElementRef>;
const directiveElements = this.directiveElementsQL.toArray();
Here without {read: ElementRef}, it won't work. We need it to tell Angular we are actually looking for the host element of the directive. Not direcitve itself.
But still the same problem as Tempalte Ref, we need to mark in the template to tell which component we need.
3. Similar to using directive only, but {read: <interface>}.
We create a Animal interface and the component implements Animal interface.
animal.ts:
export abstract class Animal {
name: string;
abstract speak(): void;
abstract clear(): void;
}
dog.component.ts:
import { Component } from '@angular/core';
import { Animal } from './animal';
@Component({
// tslint:disable-next-line:component-selector
selector: 'dog',
template: `
<div>
<img src="../assets/dog.jpg"/>
<h3>{{saying}}</h3>
</div>
`,
})
// Subclasses Animal
export class DogComponent extends Animal {
name = 'Dog';
saying: string;
speak() {
this.saying = 'Woof';
}
clear() {
this.saying = '';
}
}
Now what we can do is Query by Animal interface in the contianer component:
<cat animal ></cat>
@ContentChildren(AnimalDirective, {read: Animal}) directiveAnimalsQL: QueryList<Animal>;
const directiveAnimals = this.directiveAnimalsQL.toArray();
console.log("directiveAnimals", directiveAnimals);
/*
CatComponent {injector: Injector_, name: "Cat"}
DogComponent {name: "Dog"}
FoxComponent {name: "Fox"}
VikingComponent {name: "Viking"}
*/
4. Recommended: Finally we come to our recommended solution.
Using alias Injection of the component itself.
import { Component } from '@angular/core';
import { Animal } from './animal';
@Component({
// tslint:disable-next-line:component-selector
selector: 'fox',
template: `
<div>
<img src="../assets/fox.jpeg"/>
<h3>{{saying}}</h3>
</div>
`,
providers: [
{ provide: Animal, useExisting: FoxComponent }
]
})
export class FoxComponent implements Animal {
name = 'Fox';
saying: string;
speak() {
this.saying = 'ring-ding-ding-ding-dingedinging';
}
clear() {
this.saying = '';
}
}
For the animals related component, we inject the provider 'useExisting', so it always refer to the same instance. And we use interface Animal as alias.
Now, our container can be really clean:
<cat ></cat>
<dog></dog>
// Any projected component with an Animal "interface" in its injector
@ContentChildren(Animal) animalsQL: QueryList<Animal>;
ngAfterContentInit() {
const animals = this.animalsQL.toArray();
}
[Angular] Advanced DI的更多相关文章
- [Angular 2] DI in Angular 2 - 1
Orgial aritial --> Link The problem with Angular 1 DI: Angular 2 DI: Solve the singletons problem ...
- [Angular] Angular Advanced Features - ng-template , ng-container, ngTemplateOutlet
Previously we have tab-panel template defined like this: <ul class="tab-panel-buttons" ...
- 来自 Thoughtram 的 Angular 2 系列资料
Angular 2 已经正式 Release 了,Thoughtram 已经发布了一系列的文档,对 Angular 2 的各个方面进行深入的阐释和说明. 我计划逐渐将这个系列翻译出来,以便对大家学习 ...
- Angular概念纵览
Conceptual Overview Template(模板): HTML with additional markup (就是增加了新的标记的HTML) Directive(指令): extend ...
- (七)理解angular中的module和injector,即依赖注入
(七)理解angular中的module和injector,即依赖注入 时间:2014-10-10 01:16:54 阅读:63060 评论:1 收藏:0 [点 ...
- angular问题总结与反思
因为工作中实际开发需要,才开始接触angular框架.从当初的比葫芦画瓢,被各种问题.概念折磨摧残,到现在有一定的了解认识,觉得有必要将自己的认识进行简单的总结.不到位的地方还望多多包涵. 1.双向数 ...
- [Angular 2] Understanding @Injectable
In order to resolve a dependency, Angular’s DI uses type annotations. To make sure these types are p ...
- [Angular 2] Factory Provider with dependencies
This lesson discusses when and how to add dependencies, resolved by Angular’s DI, to factory provide ...
- [Angular 2] Factory Provider
In this lesson, we discuss how and when to use factory providers, to enable dependencies that should ...
随机推荐
- vmware centos7 没有网络设备
vmware centos7 没有网络设备 选择VMware 虚拟机模拟器为CentOS 64 即可;
- WingIDE4.1 破解及支持中文设置
1.下面提供最新版本的破解方法. 先到http://wingware.com/downloads/wingide下载最新版本的IDE. 安装之前,先修改时间到一个月前. 安装 安装之后然后获取试用版的 ...
- XML案例(使用JAXP进行SAX解析)
1.Book.java package cn.itcast.sax; public class Book { private String name; private String author; p ...
- 8.19noip模拟题
2017 8.19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c/pas ...
- [Apple开发者帐户帮助]三、创建证书(3)创建企业分发证书
作为Apple Developer Enterprise Program的成员,您可以创建多个企业分发证书. 所需角色:帐户持有人或管理员. 在证书,标识符和配置文件中,从左侧的弹出菜单中选择iOS, ...
- BZOJ 4010 拓扑排序+heap
思路: 反向图求最大拓扑序 反向输出 //By SiriusRen #include <queue> #include <cstdio> #include <cstrin ...
- 记录一个MySQL的问题
昨天做asp.net mvc程序,用mysql.data.entity.ef6做数据连接. 程序都是正常的,但就是提交数据的时候总是提示 Specified key was too long; max ...
- "etc/profile" E212: Can't open file for writing
今天安装Java环境,出现如下错误: "etc/profile" E212: Can't open file for writing 这是安装到本地JDK路径不正确导致.怎么办呢? ...
- css3中的box-sizing属性的使用
box-sizing属性用来定义元素的width和height所表示的区域,该属性一般有三种值:content-box.border-box.inherit. 其中inherit表示box-sizin ...
- angular js 正序倒叙
<!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...