[Angular 2] 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.

 

posted @   Zhentiw  阅读(1456)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示