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
   @ContentChildren('item') itemRefsQL: QueryList<any>>
   const items = this.itemRefsQL.toArray();

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
   import { Animal } from './animal';
  @ContentChildren(Animal) animalsQL: QueryList<Animal>;

  ngAfterContentInit() {
const animals = this.animalsQL.toArray();
}

Talk, Github

[Angular] Advanced DI的更多相关文章

  1. [Angular 2] DI in Angular 2 - 1

    Orgial aritial --> Link The problem with Angular 1 DI: Angular 2 DI: Solve the singletons problem ...

  2. [Angular] Angular Advanced Features - ng-template , ng-container, ngTemplateOutlet

    Previously we have tab-panel template defined like this: <ul class="tab-panel-buttons" ...

  3. 来自 Thoughtram 的 Angular 2 系列资料

    Angular 2 已经正式 Release 了,Thoughtram 已经发布了一系列的文档,对 Angular 2 的各个方面进行深入的阐释和说明. 我计划逐渐将这个系列翻译出来,以便对大家学习 ...

  4. Angular概念纵览

    Conceptual Overview Template(模板): HTML with additional markup (就是增加了新的标记的HTML) Directive(指令): extend ...

  5. (七)理解angular中的module和injector,即依赖注入

    (七)理解angular中的module和injector,即依赖注入 时间:2014-10-10 01:16:54      阅读:63060      评论:1      收藏:0      [点 ...

  6. angular问题总结与反思

    因为工作中实际开发需要,才开始接触angular框架.从当初的比葫芦画瓢,被各种问题.概念折磨摧残,到现在有一定的了解认识,觉得有必要将自己的认识进行简单的总结.不到位的地方还望多多包涵. 1.双向数 ...

  7. [Angular 2] Understanding @Injectable

    In order to resolve a dependency, Angular’s DI uses type annotations. To make sure these types are p ...

  8. [Angular 2] Factory Provider with dependencies

    This lesson discusses when and how to add dependencies, resolved by Angular’s DI, to factory provide ...

  9. [Angular 2] Factory Provider

    In this lesson, we discuss how and when to use factory providers, to enable dependencies that should ...

随机推荐

  1. PCB WCF Web接口增减参数后,在客户端不更新的情况,是否影响客户端,评估测试

    1.目的:由于接口众多,服务端变更接口,会造成服务停用更新,造成客户端不能使用或报错, 在此评估[Web中心]此服务端,接口接口参数增加或减少,是否对客户端造成影响 2.评估内容:服务端增加单值参数, ...

  2. Cash Machine(多重背包)

    http://poj.org/problem?id=1276 #include <stdio.h> #include <string.h> ; #define Max(a,b) ...

  3. .Net Core项目上Azure Docker云

    1.找到创建资源-容器-Container Instances 2.安装模板,填写私有映像表的相关信息 3.创建成功,运行测试.

  4. POJ 2823 线段树 Or 单调队列

    时限12s! 所以我用了线段树的黑暗做法,其实正解是用单调队列来做的. //By SiriusRen #include <cstdio> #include <cstring> ...

  5. 5.26 idea生成javadoc

  6. Md2All,把图片轻松上传到云图床,自动生成Markdown

    内容目录 关于Md2AllMd2All的云图床效果直接把图片拖到编辑框截图,直接复制粘贴点图片图标选择图片注册七牛云帐号新建七牛云存储空间设置云图床密钥AK和SKBucketName和BucketDo ...

  7. SQL Server存储过程作业(二)

    阶段1:练习——统计某类型客房的入住客人人数 需求说明 使用存储过程统计在指定类型的客房入住客人的总人数 提示: 存储过程的输入参数是指定的客房类型名称 USE Hotel GO --阶段1:查询入住 ...

  8. C++:C++在图片特定区域之外产生随机数

    参考原文:C++产生随机数 (整数) C++在图片特定区域之外产生随机数,避开正则表达式,可以分为两种情况. 第一种:在某个数之前生成随机数:第二种,生成随机数,加上某个数,然后截断:第三种,指定范围 ...

  9. Python批量添加库搜索路径

    被win10 给坑了,换回Win7. 重装系统后,继续使用Python,Eclipse不用重装,pydev不用重装,只需重装Python2.7.6 X64 for win即可.然后,默认已安装的Pyt ...

  10. 《计算机图形学基础(OpenGL版)》使用院校(更新)

    从清华大学出版社责任编辑处获悉,很多高等院校选用了我们这本教材,读者反应不错! 另外,编辑提供了一份详细的使用院校名单如下: 河南科技学院 中原工学院 河北工程大学 防空兵学院 伊犁师院电信学院 吉林 ...