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与Prototype并存的冲突的解决方法
Aug 29 Javascript
JQuery 风格的HTML文本转义
Jul 01 Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
Dec 06 Javascript
JS控制阿拉伯数字转为中文大写示例代码
Sep 04 Javascript
Jquery获得控件值的三种方法总结
Feb 13 Javascript
JS 作用域与作用域链详解
Apr 07 Javascript
简述jQuery ajax的执行顺序
Jan 05 Javascript
JS+WCF实现进度条实时监测数据加载量的方法详解
Dec 19 Javascript
Vue瀑布流插件的使用示例
Sep 19 Javascript
微信网页登录逻辑与实现方法
Apr 29 Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 Javascript
如何使用50行javaScript代码实现简单版的call,apply,bind
Aug 14 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中substr()与explode()函数用法分析
2014/11/24 PHP
php下Memcached入门实例解析
2015/01/05 PHP
thinkPHP3.2简单实现文件上传的方法
2016/05/16 PHP
浅谈laravel5.5 belongsToMany自身的正确用法
2019/10/17 PHP
JavaScrip单线程引擎工作原理分析
2010/09/04 Javascript
Javascript 正则表达式实现为数字添加千位分隔符
2015/03/10 Javascript
javascript下拉列表菜单的实现方法
2015/11/18 Javascript
JavaScript 中 avalon绑定属性总结
2016/10/19 Javascript
用 js 的 selection range 操作选择区域内容和图片
2017/04/18 Javascript
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
解决Js先触发失去焦点事件再执行点击事件的问题
2018/08/30 Javascript
JavaScript 点击触发复制功能实例详解
2018/11/02 Javascript
Vue数据绑定简析小结
2019/05/07 Javascript
vue实现户籍管理系统
2020/05/29 Javascript
JS出现404错误原理及解决方案
2020/07/01 Javascript
[37:03]完美世界DOTA2联赛PWL S3 INK ICE vs GXR 第二场 12.16
2020/12/18 DOTA
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
Python实现TCP/IP协议下的端口转发及重定向示例
2016/06/14 Python
Python中str.format()详解
2017/03/12 Python
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
2019/04/03 Python
python简单区块链模拟详解
2019/07/03 Python
Django连接数据库并实现读写分离过程解析
2019/11/13 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
2020/12/31 Python
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
巴西一家专门从事家居和装饰的连锁店:Camicado
2019/08/14 全球购物
介绍一下Java的安全机制
2012/06/28 面试题
新郎新娘婚礼答谢词
2014/01/11 职场文书
个人自我评价范文
2014/02/05 职场文书
晨会主持词
2014/03/17 职场文书
《最大的麦穗》教学反思
2014/04/17 职场文书
银行求职自荐信
2014/06/30 职场文书
监察局领导班子四风问题整改措施思想汇报
2014/10/05 职场文书
幼儿园小班教师个人工作总结
2015/02/06 职场文书
志愿服务心得体会
2016/01/15 职场文书
详解MySQL中的主键与事务
2021/05/27 MySQL
详细聊聊浏览器是如何看闭包的
2021/11/11 Javascript