最近在写一个日期选择器组件,为了满足将来可能出现的各种需求,所以需要能够高度的自定义组件的样式。为了达到这个目的,需要能够在日期选择器组件外控制每个日期格子内要显示的内容,比如,标上节假日之类的。这时候,组件的一部分模板就需要由调用方提供。
在 React 里面,这种需求挺简单的,只要实现一个 date => Element
这样的函数就好了,但是 Angular 模板是纯粹的模板,需要使用一些专门的概念才能实现这个功能。
第一种方式 <ng-content>
<ng-content> 这个标签到本文撰写时为止,还没有官方的文档,甚至连占位符都没有。但是这并不妨碍我们的使用,外国热心网友已经总结出了 <ng-content> 在现阶段的特点与作用。
基本用法
<!-- Wrapper.Component.html --> <div> hello <ng-content></ng-content> </div>
假设我们有一个上述的组件,然后向下面这样调用:
<wrapper> <span> World </span> </wrapper>
那么最终的渲染结果将会是这样的:
<div> hello <span> World </span> </div>
看起来就是发生了很简单的替换,但是如果在 Wrapper 中出现了多个 <ng-content>
会出现多个 <span> World </span> 吗?答案是不会的。<ng-content>
的本质只是移动元素,并不会去自动的创建传入的模板,所以就算用 ngFor 套住 <ng-content>
也不会出现很多个 <span> World </span>。如果传入的是自定义的组件,这些组件也只会被实例化一次。
进阶用法
当然,如果 <ng-content>
的功能仅仅只是这样就显得太鸡肋了,在使用 <ng-content>
的时候可以指定一个选择器,这个选择器可以捕获相符的直接子元素。例如:
<!-- Wrapper.Component.html --> <div> hello <ng-content></ng-content> <hr/> <ng-content select="span"></ng-content> </div>
然后像下面这样使用:
<wrapper> <span> World </span> 2333 </wrapper>
最终的渲染结果将会是这样:
<div> hello 2333 <hr/> <span> World </span> </div>
除了设置 ng-content
标签的 select 属性之外,还可以在子元素上使用 ngProjectAs 属性,这个属性可以让这个元素被父元素中指定的 ng-content 所捕获。举个例子:
<wrapper> <div ngProjectAs="span"> World </div> 2333 </wrapper>
这次被传入的模板变成了一个 div,但是因为设置了 ngProjectAs,所以“World”会出现在分割线下方。
第二种方式 NgTemplateOutlet 指令
使用 ng-content
确实可以起到传入模板的效果,但是却有个很致命的问题,就是无法传递数据到传入的模板中。为了将数据传递到传入的模板中,就需要使用到 NgTemplateOutlet 指令。
基本使用
这个指令可以用来在模板的指定位置实例化一个 TemplateRef 对象,同时,在实例化的过程中还可以传入一个数据对象。而 TemplateRef 可以通过 ng-template 标签来创建,举个例子:
@Component({ selector: 'ng-template-outlet-example', template: ` <ng-container *ngTemplateOutlet="name; context: myContext"></ng-container> <ng-template #name let-name="data"><span>Hello {{name}}!</span></ng-template> ` }) class NgTemplateOutletExample { myContext = {data: 'World'}; }
ng-container
是一个虚拟的元素,在这个元素上我们使用了一个 NgTemplateOutlet 指令,指定了要实例化下面的名为 name 的 ng-template。同时把 myContext 这个对象作为实例化的数据上下文传入,所以最终就会显示 “Hello World!”。值得注意的是在 ng-template 里面获取传输的数据上下文的方式:let-variableName='key'
。
进阶使用
接下来就要实现本文开头提到的需求了,在组件外部传入模板。还是以上面的例子为例,因为模板需要由外界作为子内容传入,所以需要我们手动来捕获模板,这里需要就需要使用 ContentChild:
@Component({ selector: 'wrapper', template: ` <ng-container *ngTemplateOutlet="name; context: myContext"></ng-container> ` }) class NgTemplateOutletExample { @ContentChild(TemplateRef) name: TemplateRef<any>; myContext = {data: 'World'}; }
就是这么简单的改动就可以让我们的组件从外界接受模板了,来试一试:
<wrapper> <ng-template let-value="data"> <span>Hello {{value}}!</span> </ng-template> </wrapper>
总结
以上就是 Angular 中向组件传递模板的两种方法,其中,使用 <ng-content>
标签可以更方便的控制传入的模板在 DOM 中的位置,而 NgTemplateOutlet 可以向传入的模板传递渲染数据,两者搭配使用可以起到很好的效果。
以上所述是小编给大家介绍的Angular 向组件传递模板的两种方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]