[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 ...
随机推荐
- idea导入ssm项目启动tomcat报错404
用idea写ssm项目,基于之前一直在用spring boot 对于idea如何运行ssm花费了一番功夫 启动Tom act一直在报404 我搜了网上各种解决办法都不行,花费一天多的时间解决不了 就 ...
- C#,Java,MD5加密对等实现
1.c#实现 /* *加密生成MD5 */ public static String MD5(string s) { ', 'a', 'b', 'c', 'd', 'e', 'f' }; MD5 md ...
- UOJ 129/BZOJ 4197 寿司晚宴 状压DP
//By SiriusRen #include <cstdio> #include <algorithm> using namespace std; ; struct Node ...
- X - Vasya and Socks
Problem description Vasya has n pairs of socks. In the morning of each day Vasya has to put on a pai ...
- 【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)
C. Journey time limit per test3 seconds memory limit per test256 megabytes inputstandard input outpu ...
- NSLayoutConstraints加动画来改变约束
// // ViewController.m // NSLayoutAnimationDemo // // Created by ebaotong on 15/7/22. // Copyright ( ...
- python--6、logging模块
logging 可用的日志级别: debug 10 info 20 warning 30 error 40 critical 50 logging默认参数: 默认日志级别是warning. 默认情况日 ...
- 华为 荣耀 等手机解锁BootLoader
下载工具按提示操作即可 链接:https://pan.baidu.com/s/1qZezd1q 密码:8pad 备用链接:https://pan.baidu.com/s/1nwv0heD
- DE2之7-segment displays
以前课题用的是友晶的DE2-70,现在重拾FPGA,选了一款性价比高的DE2.恰逢闲来无事,于是尝试将各个Verilog模块翻译成VHDL,半算回顾以前的知识,半算练习VHDL. Verilog 01 ...
- 【sqli-labs】 less17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
这是一个重置密码界面,查看源码可以看到username作了防注入处理 逻辑是先通过用户名查出数据,在进行密码的update操作 所以要先知道用户名,实际情况中可以注册用户然后实行攻击,这里先用admi ...