Angular利用内容投射向组件输入ngForOf模板的方法


Posted in Javascript onMarch 05, 2018

现在,我们写一个组件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"
  }
 ]
}

效果就行这样:

Angular利用内容投射向组件输入ngForOf模板的方法

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

Angular利用内容投射向组件输入ngForOf模板的方法

这就是本文的重点了。我们需要实现用户自定义模板!

现在我们不写死组件的模板了,而是让用户从外部输入!

首先,我们的组件模板:

<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可以查看这里,需FQ)获取到外部(相对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>
`
})

效果还是一样的:

Angular利用内容投射向组件输入ngForOf模板的方法

如果我们只要显示小狗狗的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>
`
})

效果就像这样:

Angular利用内容投射向组件输入ngForOf模板的方法

这样的组件很灵活,想要什么样的效果都可以定制,这就实现了组件的复用。

好了,本文就到此为止了。不当之处,欢迎指出!希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE 下的只读 innerHTML
Aug 21 Javascript
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
来自国外的14个图片放大编辑的jQuery插件整理
Oct 20 Javascript
js通过地址栏给action传值(中文乱码全是问号)
May 02 Javascript
解析JavaScript中delete操作符不能删除的对象
Dec 03 Javascript
JS中的构造函数详细解析
Mar 10 Javascript
javascript获取checkbox复选框获取选中的选项
Aug 12 Javascript
jquery dataview数据视图插件使用方法
Dec 23 Javascript
解决vue keep-alive 数据更新的问题
Sep 21 Javascript
RxJS的入门指引和初步应用
Jun 15 Javascript
jQuery位置选择器用法实例分析
Jun 28 jQuery
JS中的变量作用域(console版)
Jul 18 Javascript
axios全局请求参数设置,请求及返回拦截器的方法
Mar 05 #Javascript
axios拦截设置和错误处理方法
Mar 05 #Javascript
完美解决axios在ie下的兼容性问题
Mar 05 #Javascript
vue.js 使用axios实现下载功能的示例
Mar 05 #Javascript
Vue 中使用vue2-highcharts实现top功能的示例
Mar 05 #Javascript
Vue 中使用vue2-highcharts实现曲线数据展示的方法
Mar 05 #Javascript
vue项目中引入noVNC远程桌面的方法
Mar 05 #Javascript
You might like
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
yii2分页之实现跳转到具体某页的实例代码
2016/06/02 PHP
laravel 事件/监听器实例代码
2019/04/12 PHP
抽出www.templatemonster.com的鼠标悬停加载大图模板的代码
2007/07/11 Javascript
JQuery 应用 JQuery.groupTable.js
2010/12/15 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
给ListBox添加双击事件示例代码
2013/12/02 Javascript
使用Javascript简单实现图片无缝滚动
2014/12/05 Javascript
javascript函数命名的三种方式及区别介绍
2016/03/22 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
2017/06/12 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
cnpm加速Angular项目创建的方法
2018/09/07 Javascript
js核心基础之闭包的应用实例分析
2019/05/11 Javascript
JS实现的检验身份证格式并输出出生日期,年龄,性别,出生地示例
2019/05/17 Javascript
Ajax请求时无法重定向的问题解决代码详解
2019/06/21 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
[51:52]Liquid vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
简单了解django orm中介模型
2019/07/30 Python
简单了解Python多态与属性运行原理
2020/06/15 Python
Python模拟登录和登录跳转的参考示例
2020/10/30 Python
python实现图片,视频人脸识别(dlib版)
2020/11/18 Python
Scrapy实现模拟登录的示例代码
2021/02/21 Python
经济管理专业毕业生推荐信
2013/11/11 职场文书
营销人才自我鉴定范文
2013/12/25 职场文书
师范教师毕业鉴定
2014/01/13 职场文书
商务日语专业的自荐信
2014/05/23 职场文书
党员一帮一活动总结
2014/07/08 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
爱国主义教育主题班会
2015/08/13 职场文书
Python 类,对象,数据分类,函数参数传递详解
2021/09/25 Python
python 标准库原理与用法详解之os.path篇
2021/10/24 Python
python脚本框架webpy模板赋值实现
2021/11/20 Python
python分分钟绘制精美地图海报
2022/02/15 Python