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 相关文章推荐
动态控制Table的js代码
Mar 07 Javascript
DOMAssitant最新版 DOMAssistant 2.5发布
Dec 25 Javascript
javascript+mapbar实现地图定位
Apr 09 Javascript
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
Dec 13 Javascript
纯js写的分页表格数据为json串
Feb 18 Javascript
jquery操作对象数组元素方法详解
Nov 26 Javascript
js控制输入框获得和失去焦点时状态显示的方法
Jan 30 Javascript
Angularjs手动解析表达式($parse)
Oct 12 Javascript
js实现登录验证码
Dec 22 Javascript
js实现手机拍照上传功能
Jan 17 Javascript
Vuex实现数据增加和删除功能
Nov 11 Javascript
jQuery实现容器间的元素拖拽功能
Dec 01 jQuery
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快递单号查询接口使用示例
2014/05/05 PHP
destoon供应信息title调用出公司名称的方法
2014/08/22 PHP
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
解析jQuery与其它js(Prototype)库兼容共存
2013/07/04 Javascript
js中通过split函数分割字符串成数组小例子
2013/09/21 Javascript
js类型转换与引用类型详解(Boolean_Number_String)
2014/03/07 Javascript
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
使用js画图之饼图
2015/01/12 Javascript
js实现将选中值累加到文本框的方法
2015/08/12 Javascript
今天抽时间给大家整理jquery和ajax的相关知识
2015/11/17 Javascript
JavaScript中判断数据类型的方法总结
2016/05/24 Javascript
用jQuery实现优酷首页轮播图
2017/01/09 Javascript
JavaScript 用fetch 实现异步下载文件功能
2017/07/21 Javascript
AngularJS路由删除#符号解决的办法
2017/09/28 Javascript
Angular 利用路由跳转到指定页面的指定位置方法
2018/08/31 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
简单了解vue 插值表达式Mustache
2020/07/22 Javascript
基于原生JS封装的Modal对话框插件的示例代码
2020/09/09 Javascript
[01:42]TI4西雅图DOTA2前线报道 第一顿早饭哦
2014/07/08 DOTA
[04:05]TI9战队采访 - Natus Vincere
2019/08/22 DOTA
python socket网络编程步骤详解(socket套接字使用)
2013/12/06 Python
对python中使用requests模块参数编码的不同处理方法
2018/05/18 Python
Python使用装饰器模拟用户登陆验证功能示例
2018/08/24 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
python矩阵的转置和逆转实例
2018/12/12 Python
python批量识别图片指定区域文字内容
2019/04/30 Python
python 字符串常用函数详解
2019/09/11 Python
浅谈图像处理中掩膜(mask)的意义
2020/02/19 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
职业生涯规划书基本格式
2014/01/06 职场文书
马智宇结婚主持词
2014/04/01 职场文书
环保标语大全
2014/06/12 职场文书
合唱兴趣小组活动总结
2014/07/10 职场文书
党员干部对十八届四中全会的期盼
2014/10/17 职场文书
2014年销售部工作总结
2014/12/01 职场文书
解读Vue组件注册方式
2021/05/15 Vue.js