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 相关文章推荐
计算新浪Weibo消息长度(还可以输入119字)
Jul 02 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
Jul 07 Javascript
超炫的jquery仿flash导航栏特效
Nov 11 Javascript
做web开发 先学JavaScript
Dec 12 Javascript
js中跨域方法原理详解
Jul 19 Javascript
jquery实现红色竖向多级向右展开的导航菜单效果
Aug 31 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
Oct 19 Javascript
微信小程序的日期选择器的实例详解
Sep 29 Javascript
vue-cli2.9.3 详细教程
Apr 23 Javascript
微信小程序如何调用图片接口API并居中显示
Jun 29 Javascript
解决echarts echarts数据动态更新和dataZoom被重置问题
Jul 20 Javascript
用webAPI实现图片放大镜效果
Nov 23 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程序?
2006/12/08 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
PHP中spl_autoload_register函数的用法总结
2013/11/07 PHP
js判断浏览器类型为ie6时不执行
2014/06/15 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
jquery实现的淡入淡出下拉菜单效果
2015/08/25 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
纯JS代码实现一键分享功能
2016/04/20 Javascript
JS实现的简单图片切换功能示例【测试可用】
2017/02/14 Javascript
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
使用Bootstrap打造特色进度条效果
2017/05/02 Javascript
fetch 使用及如何接收JS传值
2017/11/11 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
JS/jQuery实现获取时间的方法及常用类完整示例
2019/03/07 jQuery
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
这样回答继承可能面试官更满意
2019/12/10 Javascript
Vue 图片压缩并上传至服务器功能
2020/01/15 Javascript
[01:38]完美世界高校联赛决赛花絮
2018/12/02 DOTA
浅析Python中的序列化存储的方法
2015/04/28 Python
python爬虫实战之最简单的网页爬虫教程
2017/08/13 Python
Selenium的使用详解
2018/10/19 Python
Python使用字典的嵌套功能详解
2019/02/27 Python
Python求凸包及多边形面积教程
2020/04/12 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
西班牙三叶草药房:Farmacias Trébol
2019/05/03 全球购物
应届毕业生个人自荐信范文
2013/11/30 职场文书
酒店实习个人鉴定
2013/12/07 职场文书
请假条的格式
2014/04/11 职场文书
软件测试专业推荐信
2014/09/18 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
信用卡工资证明范本
2014/10/17 职场文书
关于实现中国梦的心得体会
2016/01/05 职场文书
Python 多线程之threading 模块的使用
2021/04/14 Python
python opencv将多个图放在一个窗口的实例详解
2022/02/28 Python