[Angular 2] 4. RC7: More on *ngFor, @ContentChildren & QueryList<>

In previous artical, we introduce the how to use *ngFor. The limitation for previous solution to display all the heros is we hard cord all heros in our heroes component. First, in real world app, we cannot hard cord;  Seond, even we don‘t hard code, do http instead, it is still not good enough. We should leave Heroes component as dump component, just rendering the ui, no logic should be involved.

So instead of doing this in app.ts:

@Component({
    selector: ‘app‘,
    template: `
            <heroes>
            </heroes>
        `
})

We try another way like this:

@Component({
    selector: ‘app‘,
    template: `

            <heroes>
                <hero name="Superman" id="1"></hero>
                <hero name="Batman" id="2"></hero>
                <hero name="BatGirl" id="3"></hero>
                <hero name="Robin" id="4"></hero>
                <hero name="Flash" id="5"></hero>
                <hero name="Zhentian" id="6"></hero>
            </heroes>

        `
})

Well, I know, still hard code, but just show how ngFor can be used.

Now, inside ‘heroes‘ tag, we add now ‘hero‘ tag. And we want to display those inside ‘heroes‘ component:

import {Component, ContentChildren, QueryList} from "@angular/core";
import {Hero} from ‘./hero‘;
/*
const HEROES = [
    {id: 1, name:‘Superman‘},
    {id: 2, name:‘Batman‘},
    {id: 5, name:‘BatGirl‘},
    {id: 3, name:‘Robin‘},
    {id: 4, name:‘Flash‘}
];*/

@Component({
    selector:‘heroes‘,
    styleUrls: [
        ‘heroes.component.css‘
    ],
    template: `
    <table>
        <thead>
            <th>Name</th>
            <th>Index</th>
        </thead>
        <tbody>
            <tr *ngFor="let hero of heroes; let i = index; trackBy: trackBy(hero);
             let isEven=even; let isFirst=first; let isLast=last;"
             [ngClass]="{‘even‘: isEven, ‘first‘: isFirst, ‘last‘: isLast}">
                <td>{{hero.name}}</td>
                <td>{{i}}</td>
            </tr>
        </tbody>
    </table>
`
})
export class Heroes {
    //heroes = HEROES;
    @ContentChildren(Hero)
    heroes: QueryList<Hero>

    trackBy(hero){
        return hero ? hero.id: undefined;
    }
}

You can see, we have commented out the hard code array. Instead, we use:

    @ContentChildren(Hero)
    heroes: QueryList<Hero>

‘Hero‘ here, is a element directive:

import {Directive, Input} from "@angular/core";

@Directive({
    selector: ‘hero‘,
})
export class Hero {

    @Input()
    id: number;

    @Input()
    name:string;

}

@ContentChildren will check the Children in HTML DOM tree, which will get:

                <hero name="Superman" id="1"></hero>
                <hero name="Batman" id="2"></hero>
                <hero name="BatGirl" id="3"></hero>
                <hero name="Robin" id="4"></hero>
                <hero name="Flash" id="5"></hero>
                <hero name="Zhentian" id="6"></hero>

QueryList<Hero>: Only get ‘Hero‘ directive.

QueryList is a class provided by Angular and when we use QueryList with a ContentChildren Angular populate this with the components that match the query and then keeps the items up to date if the state of the application changes .

However, QueryList requires a ContentChildren to populate it, so let’s take a look at that now.

What‘s cool about *ngFor, it not only accpets Array, but also any iterable type, we have list of DOM element ‘hero‘, which are iterable, so ngFor will able to display those also.

时间: 2024-10-02 19:33:49

[Angular 2] 4. RC7: More on *ngFor, @ContentChildren & QueryList<>的相关文章

[Angular 2] 3. RC7: *ngFor

heros.ts: import {Component} from "@angular/core"; const HEROES = [ {id: 1, name:'Superman'}, {id: 2, name:'Batman'}, {id: 5, name:'BatGirl'}, {id: 3, name:'Robin'}, {id: 4, name:'Flash'} ]; @Component({ selector:'heroes', styleUrls: [ 'heroes.c

[Angular] @ViewChildren and QueryLists (ngAfterViewInit)

When you use @ViewChildren, the value can only be accessable inside ngAfterViewInit lifecycle. This is somehow different from @ViewChild, which value can be accessed from ngAfterContentInit lifecycle. import { Component, ChangeDetectorRef, Output, Vi

angular2自学笔记---官网项目(一)

1.单向数据绑定的'插值表达式' angular中最典型的数据显示方式:把HTML模板(template)的控件绑定到angular组件的属性(component相当于一个构造函数,下面例子中的这个构造函数有name.title.和hero三个属性)简单来说就是把组件的属性名放到显示曾{{属性名}}中,angular负责喷到页面中:angular从组件中提取属性插入浏览器,然后angular会自动监听这些属性值的变化,一旦属性值发生变化,angular会自动刷新显示,这里的刷新,严格意义上指的是

[Angular 2] Using ng-for to repeat template elements

This lesson covers Angular 2’s version of looping through data in your templates: ng-for. It’s conceptually the same as Angular 1’s ng-repeat, but you’ll find the syntax quite different as it aligns with #refs in Angular 2 and JavaScript “for of” loo

[Angular 2] ngFor

It’s conceptually the same as Angular 1’s ng-repeat, but you’ll find the syntax quite different as it aligns with #refs in Angular 2 and JavaScript “for of” loop. import {Component, View, NgFor} from 'angular2/angular2'; import {TodoService} from './

[Angular 2] *ngFor with index

Let's see how to track index when we use 'ngFor: <li *ngFor="#hero of heros | async, #i = index"> <hero-item [hero]="hero" (changed)="thisHero = $event;" [index]="i"></hero-item> </li> #i = i

转发: Angular装饰器

Angular中的装饰器是一个函数,它将元数据添加到类.类成员(属性.方法)和函数参数. 用法:要想应用装饰器,把它放在被装饰对象的上面或左边. Angular使用自己的一套装饰器来实现应用程序各部件之间的相互操作. 这个地方是前面几个模块(Modules), 指令(Diretives).组件(Components).依赖注入(Dependency Injection)等从装饰器这个侧面的整理. 你需要做的: 1.搞清楚理解TypeScript的装饰器原理. 2.搞清楚这里面每一个装饰器的作用,

Angular基础(二) 组件的使用

? 一.简单操作 a) 使用Angular CLI可以快速创建项目框架,先运行 $ npm install –g @angular/[email protected]安装CLI,为CLI的位置设置环境变量,然后就可以全局使用ng命令了. 执行ng new –ng4 angular-hello-world可以创建Angular4项目,会自动生成基础的文件夹和文件,还会自动进行npm i操作,下载并安装所需的依赖. 然后执行ng serve就可以编译并启动这个程序了,但ng并不会自动打开浏览器. b

Angular 4+ HttpClient

这篇,算是上一篇Angular 4+ Http的后续: Angular 4.3.0-rc.0 版本已经发布??.在这个版本中,我们等到了一个令人兴奋的新功能 - HTTPClient API 的改进版本: HttpClient 是已有 Angular HTTP API 的演进,它在一个单独的 @angular/common/http 包中.这是为了确保现有的代码库可以缓慢迁移到新的 API: 大多数前端应用都需要通过 HTTP 协议与后端服务器通讯.现代浏览器支持使用两种不同的 API 发起 H