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 相关文章推荐
Jquery 1.42 checkbox 全选和反选代码
Mar 27 Javascript
跟我学习javascript的定时器
Nov 19 Javascript
对Js OOP编程 创建对象的一些全面理解
Jul 26 Javascript
chrome浏览器如何断点调试异步加载的JS
Sep 05 Javascript
jQuery使用getJSON方法获取json数据完整示例
Sep 13 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
Jan 13 Javascript
jQuery与vue实现拖动验证码功能
Jan 30 jQuery
JavaScript指定断点操作实例教程
Sep 18 Javascript
JS实现图片拖拽交换效果
Nov 30 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
Feb 27 jQuery
js将URL网址转为16进制加密与解密函数
Mar 04 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面向对象精要总结
2014/11/07 PHP
PHP生成唯一订单号
2015/07/05 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
javascript编程起步(第一课)
2007/01/10 Javascript
如何判断图片地址是否失效
2007/02/02 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
jQuery中多个元素的Hover事件解决方案
2014/06/12 Javascript
js和C# 时间日期格式转换的简单实例
2016/05/28 Javascript
JS遍历ul下的li点击弹出li的索引的实现方法
2016/09/19 Javascript
JS实现的样式切换功能tableCSS实例
2016/12/30 Javascript
JS排序算法之冒泡排序,选择排序与插入排序实例分析
2017/12/13 Javascript
Vue组件开发技巧总结
2018/03/04 Javascript
在vue中,v-for的索引index在html中的使用方法
2018/03/06 Javascript
layui表格checkbox选择全选样式及功能的实例
2018/03/07 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
python解析模块(ConfigParser)使用方法
2013/12/10 Python
python 读写txt文件 json文件的实现方法
2016/10/22 Python
Python模块文件结构代码详解
2018/02/03 Python
解决Pycharm下面出现No R interpreter defined的问题
2018/10/29 Python
python制作mysql数据迁移脚本
2019/01/01 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
2021/01/27 Python
解决方案设计综合面试题
2015/08/31 面试题
实习生个人的自我评价
2013/12/08 职场文书
优秀民警事迹材料
2014/01/29 职场文书
就业自我评价
2014/02/04 职场文书
创业大赛策划书
2014/03/01 职场文书
广场舞大赛策划方案
2014/05/31 职场文书
厕所文明标语
2014/06/11 职场文书
学校交通安全责任书
2014/08/25 职场文书
影视广告专业求职信
2014/09/02 职场文书
2014年车间主任工作总结
2014/12/10 职场文书
现场施工员岗位职责
2015/04/11 职场文书
加薪通知
2015/04/25 职场文书
Python 制作自动化翻译工具
2021/04/25 Python
python opencv通过4坐标剪裁图片
2021/06/05 Python
vue递归实现树形组件
2022/07/15 Vue.js