• Angular:利用内容投射向组件输入ngForOf模板


    现在,我们写一个组件puppiesListCmp,用于显示小狗狗的列表:

    //puppies-list.component.ts
    @Component({
      selector: 'puppies-list',
      template: `
        <div *ngFor="let puppy of puppies">
          <span>{{puppy.name}}</span>
          <span>{{puppy.age}}</span>
          <span>{{puppy.color}}</span>
        </div>
    `
    })
    export class puppiesListCmp{
      @Input() puppies: Puppy[];
    }
    interface Puppy {
      name: string,
      age: number,
      color: string
    }
    

    然后这样使用:

    //app.component.ts
    @Component({
      selector: 'my-app',
      template: `
        <puppies-list [puppies]="puppies"></puppies-list>
    `
    })
    export class App{
      puppies = [
        {
          name: "sam",
          age: 0.6,
          color: "yellow"
        },
        {
          name: "bingo",
          age: 1.5,
          color: "black"
        }
      ]
    }
    

    效果就行这样:

    但是,我希望我们的puppiesListCmp组件可以满足不同的需求,比如在数据不变的情况下只显示小狗狗的name和color,就像这样:

    这就是本文的重点了。我们需要实现用户自定义模板!
    现在我们不写死组件的模板了,而是让用户从外部输入!
    首先,我们的组件模板:

    <div *ngFor="let puppy of puppies">
          <span>{{puppy.name}}</span>
          <span>{{puppy.age}}</span>
          <span>{{puppy.color}}</span>
    </div>
    

    等价于:

    <ng-template ngFor let-puppy [ngForOf]="puppies">
          <div>
            <span>{{puppy.name}}</span>
            <span>{{puppy.age}}</span>
            <span>{{puppy.color}}</span>
          </div>
    </ng-template>
    

    然后,用@ContentChild(关于@ContentChild可以查看这里,需翻墙)获取到外部(相对puppiesListCmp组件而言)自定义模板,并赋给ngForTemplate。也就是说,这部分:

    <div>
        <span>{{puppy.name}}</span>
        <span>{{puppy.age}}</span>
        <span>{{puppy.color}}</span>
    </div>
    

    不再像之前那样写死在组件里了,而是由使用者在父组件中自定义,然后利用Angular的内容投射(Content Projection),投射到puppiesListCmp组件里面。就像这样:

    //puppies-list.component.ts
    import { Component, Input, ContentChild, TemplateRef } from '@angular/core';
    import { NgForOfContext } from '@angular/common';
    @Component({
      selector: 'puppies-list',
      template: `
    <ng-template ngFor let-puppy [ngForOf]="puppies" [ngForTemplate]="tpl"></ng-template>
    `
    })
    export class puppiesListCmp{
      @Input() puppies: Puppy[];
      @ContentChild(TemplateRef) tpl: TemplateRef<NgForOfContext<Puppy>>
    }
    interface Puppy {
      name: string,
      age: number,
      color: string
    }
    

    这样我们的组件就算完成了。然后我们使用它:

    //app.component.ts
    @Component({
      selector: 'my-app',
      template: `
    <puppies-list [puppies]="puppies">
      <ng-template let-puppy>
        <div>
          <span>{{puppy.name}}</span>
          <span>{{puppy.age}}</span>
          <span>{{puppy.color}}</span>
        </div>
      </ng-template>
    </puppies-list>
    `
    })
    

    效果还是一样的:

    如果我们只要显示小狗狗的name和color,只要这样写就好了:

    //app.component.ts
    @Component({
      selector: 'my-app',
      template: `
    <puppies-list [puppies]="puppies">
      <ng-template let-puppy>
        <div>
          <span>{{puppy.name}}</span>
          <span>{{puppy.color}}</span>
        </div>
      </ng-template>
    </puppies-list>
    `
    })
    

    效果就像这样:

    这样的组件很灵活,想要什么样的效果都可以定制,这就实现了组件的复用。
    好了,本文就到此为止了。不当之处,欢迎指出!

  • 相关阅读:
    探索c#之Async、Await剖析
    探索C#之布隆过滤器(Bloom filter)
    探索C#之虚拟桶分片
    刷新本地的DNS缓存数据
    php取整函数ceil,floor,round,intval函数的区别
    这样顶级人生规划 ,想不成功都难
    全篇干货,10分钟带你读透《参与感》
    iOS审核秘籍】提审资源检查大法
    php如何遍历多维的stdClass Object 对象,php的转换成数组的函数只能转换外面一丛数组
    RDS MySQL 连接数满情况的处理
  • 原文地址:https://www.cnblogs.com/cme-kai/p/8495909.html
Copyright © 2020-2023  润新知