Angular:利用内容投射向组件输入ngForOf模板
现在,我们写一个组件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"
}
]
}
效果就行这样:

但是,我希望我们的puppiesListCmp组件可以满足不同的需求,比如在数据不变的情况下只显示小狗狗的name和color,就像这样:

这就是本文的重点了。我们需要实现用户自定义模板!
现在我们不写死组件的模板了,而是让用户从外部输入!
首先,我们的组件模板:
<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可以查看这里,需翻墙)获取到外部(相对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>
`
})
效果还是一样的:

如果我们只要显示小狗狗的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模板的更多相关文章
- Angular利用@ViewChild在父组件执行子组件的方法
代码如下: @Component({ selector: 'my-app', template: ` <step-bar #stepBar></step-bar> ` }) e ...
- Angular开发实践(八): 使用ng-content进行组件内容投射
在Angular中,组件属于特殊的指令,它的特殊之处在于它有自己的模板(html)和样式(css).因此使用组件可以使我们的代码具有强解耦.可复用.易扩展等特性.通常的组件定义如下: demo.com ...
- 使用ng-content进行组件内容投射
原文 https://www.jianshu.com/p/c0a39b1776c0 大纲 1.认识内容投射 2.一个简单组件 3.简单投射 4.针对性投射 5.ngProjectAs 6.代码资源 认 ...
- vue组件4 利用slot将内容传递给组件
除了将数据作为prop传入到组件中,vue也允许传入HTML 父组件中的子组件:<custom-button>点我<custom-button/> custom-button子 ...
- 转载——利用C#自带组件强壮程序日志
利用C#自带组件强壮程序日志 在项目正式上线后,如果出现错误,异常,崩溃等情况 我们往往第一想到的事就是查看日志 所以日志对于一个系统的维护是非常重要的 声明 正文中的代码只是一个栗子,一个非常简 ...
- Vue中利用$emit实现子组件向父组件通信
Vue中利用$emit实现子组件向父组件通信 父组件 <template> <div> <p>我是父组件</p> <child :isShow=& ...
- EditTextPreference点击后输入框显示隐藏内容,类似密码输入(转)
http://bbs.anzhuo.cn/thread-928131-1-1.html EditTextPreference点击后输入框显示隐藏内容,类似密码输入... [复制链接] aski ...
- angular利用ui-router登录检查
angular利用ui-router登录检查 SAP都会有这个问题,session过期或者页面被刷新的情况下应该进入登录页. 监听ui-router的satte事件可以实现当state切换的时候检查登 ...
- Java学习笔记之[ 利用扫描仪Scanner进行数据输入 ]
/*********数据的输入********//**利用扫描仪Scanner进行数据输入 怎么使用扫描仪Scanner *1.放在类声明之前,引入扫描仪 import java.util.Scann ...
随机推荐
- diffMerge安装配置使用
概述: 在用git进行源代码版本维护的时候,常常会进行各代码版本之前区别的查看,例如在每次提交改动前进行git diff 可以看到源文件代码相对相应版本或是远程仓库的改动情况,如果有冲突还需要进行me ...
- Oracle实战笔记(第七天)之PL/SQL进阶
一.控制结构 控制结构包括:判断语句(条件分支语句).循环语句.顺序控制语句三种. 1.条件分支语句 if--then:简单条件判断 --编写一个过程,可以输入一个雇员名,如果该雇员名的工资低于200 ...
- Django_实现分页
需求: 对于有很多数据,并不希望一次性全部展现在一个页面,需要一个分页的,定好每一页显示的内容 那,如何满足这个需求呢? 通过第三方模块 django-pure-pagination pip ins ...
- SSM与jsp传递实体类
jsp传controller Controller: @RequestMapping({"/user"}) public void registerUser(User uu) th ...
- JSP内置对象值out对象及其它的一些常见方法
out对象: out对象是jspWriter类的实例,是向客户端输出内容常用的对象. 常用方法如下: void println() 向客户端打印字符串 void clear() 清除缓冲区的内容,如果 ...
- android 设置TextView水平滚动和解决首行缩进问题
android:ellipsize="marquee" android:focusable="true" android:focusableInTouchMod ...
- 详解spl_autoload_register() 函数(转)
原文地址:http://blog.csdn.net/panpan639944806/article/details/23192267 在了解这个函数之前先来看另一个函数:__autoload. 一._ ...
- js面向对象之继承那点事儿根本就不是事
继承 说道这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名):一种是实现继承(继承实际的方法) 奈何js中没有签名,因而只有实现继承,而且 ...
- 在Web.config中配置handler
在Web.config中配置handler节点时发现用vs2010和用vs2015竟然不一样,经过多次测试发现了一些倪端: <configuration> <!--vs2010中需要 ...
- VUE-node.js
1.什么是node.js 它是可以运行javascript的服务平台 可以把它当做一门后端程序,只是它的开发语言是Javascript2.Python:自己创建的服务 php ...