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 性能优化指南(2)
May 21 Javascript
ASP中Sub和Function的区别说明
Aug 30 Javascript
更换select下拉菜单背景样式的实现代码
Dec 20 Javascript
JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载
Jun 28 Javascript
使用jquery动态加载javascript以减少服务器压力
Oct 29 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
Sep 06 Javascript
深入理解JavaScript中的浮点数
May 18 Javascript
使用JavaScriptCore实现OC和JS交互详解
Mar 28 Javascript
Vue.js中的computed工作原理
Mar 22 Javascript
小程序实现单选多选功能
Nov 04 Javascript
微信小程序实现手势滑动卡片效果
Aug 26 Javascript
vue实现简单瀑布流布局
May 28 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递归返回值时出现的问题解决办法
2013/02/19 PHP
php获取微信共享收货地址的方法
2017/12/21 PHP
用js得到网页中所有的div的id
2020/10/19 Javascript
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
Javascript图像处理—平滑处理实现原理
2012/12/28 Javascript
setInterval()和setTimeout()的用法和区别示例介绍
2013/11/17 Javascript
js 动态为textbox添加下拉框数据源的方法
2014/04/24 Javascript
AngularJS API之copy深拷贝详解及实例
2016/09/14 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
jquery animate动画持续运动的实例
2017/11/29 jQuery
Koa2 之文件上传下载的示例代码
2018/03/29 Javascript
微信小程序mpvue点击按钮获取button值的方法
2019/05/29 Javascript
javascript绘制简单钟表效果
2020/04/07 Javascript
使用Python进行稳定可靠的文件操作详解
2013/12/31 Python
用Python登录好友QQ空间点赞的示例代码
2017/11/04 Python
Python中应该使用%还是format来格式化字符串
2018/09/25 Python
不知道这5种下划线的含义,你就不算真的会Python!
2018/10/09 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
python识别图像并提取文字的实现方法
2019/06/28 Python
Django中ORM找出内容不为空的数据实例
2020/05/20 Python
在Pytorch中使用Mask R-CNN进行实例分割操作
2020/06/24 Python
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
德国baby-markt婴儿用品瑞士网站:baby-markt.ch
2017/06/09 全球购物
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
C++面试题目
2013/06/25 面试题
介绍一下gcc特性
2015/10/31 面试题
历史学专业毕业生求职信
2013/09/27 职场文书
预备党员入党思想汇报
2014/01/04 职场文书
企业委托书范本
2014/09/13 职场文书
水利局群众路线专题民主生活会发言材料
2014/09/21 职场文书
2014年社区工作总结
2014/11/18 职场文书
2019最新校园运动会广播稿!
2019/06/28 职场文书
创业计划书之美容店
2019/09/16 职场文书
导游词之西安大清真寺
2019/12/17 职场文书
Python实现列表拼接和去重的三种方式
2021/07/02 Python