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 相关文章推荐
js操作select控件的几种方法
Jun 02 Javascript
JSON 和 JavaScript eval使用说明
Jun 13 Javascript
推荐10个2014年最佳的jQuery视频插件
Nov 12 Javascript
jQuery实现HTML5 placeholder效果实例
Dec 09 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
Nov 01 Javascript
jQuery实现仿QQ头像闪烁效果的文字闪动提示代码
Nov 03 Javascript
jQuery实现标签页效果实战(4)
Feb 08 Javascript
jQuery插件ContextMenu自定义图标
Mar 15 Javascript
详解vue中引入stylus及报错解决方法
Sep 22 Javascript
vue实现商城购物车功能
Nov 27 Javascript
Angular刷新当前页面的实现方法
Nov 21 Javascript
微信小程序通过js实现瀑布流布局详解
Aug 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写的小东西
2006/12/06 PHP
PHP操作mysql函数详解,mysql和php交互函数
2011/05/19 PHP
Javascript 继承实现例子
2009/08/12 Javascript
javascript与CSS复习(二)
2010/06/29 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
2014/04/23 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
2016/05/31 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
2018/10/25 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
微信小程序 搜索框组件代码实例
2019/09/06 Javascript
Typescript的三种运行方式(小结)
2019/09/18 Javascript
vue实现侧边栏导航效果
2019/10/21 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
python检测远程udp端口是否打开的方法
2015/03/14 Python
Python记录详细调用堆栈日志的方法
2015/05/05 Python
Python入门教程之运算符与控制流
2016/08/17 Python
python使用fcntl模块实现程序加锁功能示例
2017/06/23 Python
Django基于ORM操作数据库的方法详解
2018/03/27 Python
Python 实现网页自动截图的示例讲解
2018/05/17 Python
opencv python 傅里叶变换的使用
2018/07/21 Python
Python骚操作之动态定义函数
2019/03/26 Python
Python collections中的双向队列deque简单介绍详解
2019/11/04 Python
如何通过Django使用本地css/js文件
2020/01/20 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
python爬虫---requests库的用法详解
2020/09/28 Python
html5中 media(播放器)的api使用指南
2014/12/26 HTML / CSS
利用canvas实现图片压缩的示例代码
2018/07/17 HTML / CSS
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
素食餐饮项目创业计划书
2014/02/02 职场文书
机电一体化专业毕业生自荐信
2014/06/19 职场文书
税务干部群众路线教育实践活动自我剖析材料
2014/09/21 职场文书
优秀教师先进事迹材料
2014/12/15 职场文书
iPhone13 Pro外观确定,升级4800万镜头,4月20日发新品
2021/04/15 数码科技
Python查找算法的实现 (线性、二分,分块、插值查找算法)
2022/04/24 Python