不知道怎么同步quiver笔记到手机端,决定把之前写的笔记发到这来,一篇篇搬吧 -_-
-
ng-template
使用antd组件库时常常用到,用于定义HTML模板,定义后不会直接显示,需要通过其他结构型指令(例如
ngIf)或者template-ref渲染到页面上。- 使用
ngIf渲染
<div *ngIf="isShow else testTemp"> this is a html ! (isShow为true时展示) </div> <!-- #testTemp 起的模板名称, 要求是当前的component里唯一 --> <ng-template #testTemp> this is a templateHtml ! </ng-template>TemplateRef和ViewContainerRef渲染.TemplateRef对应ng-template的引用;ViewContainerRef是容器View的引用,用来操作DOM;
@Component({ selector: 'app-template', templateUrl: ` <ng-template #testTemp> this is a templateHtml ! </ng-template> `, styleUrls: ['./app-template.component.less'], }) export class TemplateComponent { @ViewChild('testTemp') testTemp: TemplateRef<any>; constructor(private vcRef: ViewContainerRef) { } ngAfterViewInit() { // 这样testTemp对应的ng-template内容就显示出来了 this.vcRef.createEmbeddedView(this.testTemp); } }- 使用
ngTemplateOutlet渲染模板。ps: 在渲染页面之前,Angular 会把及其内容替换为注释。
<!-- testTemp 可以是组件声明的 TemplateRef 类型的模板对象; 也可以直接是同一页面里的ng-template标签声明的名称 --> <div *ngTemplateOutlet="testTemp"></div>- 了解下
ngTemplateOutlet功能: 支持上下文传参,context;
<!-- xx是在ng-template内部使用的变量名字,xx对应的值是上下文对象yy属性的值 --> <ng-template #testTemp let-xx="yy"> this is a templateHtml ! {{ xx }} </ng-template> <!-- testContext 是json对象 --> <div *ngTemplateOutlet="testTemp; context: testContext"></div> - 使用
-
ng-container
这个ng-container 既不是Component 也不是 Directive,书写时就是个html标签,但是实际页面不会生成任何元素,一般都用作逻辑处理。
- 使用场景 ngFor遍历元素时加入ngIf 控制显示。ngFor和ngIf不能同时使用这个时候就需要使用ng-container了,例如:
<ng-container *ngFor="let item of list;let i = index"> <div *ngIf="i % 2 == 0"> {{ item }} - {{i}} </div> </ng-container> -
ng-content
ng-content这个标签的功能和router-outlet类似,都像一个占位标签。 先回顾下router-outlet使用方式:出现该标签时,对应的路由配置中会有 children 属性,当触发路由时,页面会替换到router-outlet的位置。 ng-content和router-outlet功能类似,ng-content出现在组件中时,引入该组件的父组件可以替换掉ng-content。<!-- 子组件 test-child.html 页面 --> <div> 这是个子组件: <ng-content></ng-content> </div> <!-- 父组件页面 parent.html 引用时 --> <test-child> 你说的对! </test-child>最终执行完效果:
看到这,大概懂了这东西是干嘛的吧? (和Vue的
slot有点类似) 当然,这个标签不可能在一个组件里只出现一次,下面看下当一个页面里出现多个ng-content怎么使用。ng-content中有个属性select可以让你在你想要的位置投射。这个属性支持css选择器、标签选择器、属性选择器 来匹配你想要的内容。 ps:如果不设置这个属性,就会接收全部内容。select不支持动态变量。<!-- 这个是含有ng-content 标签的组件 --> <div> <div class="content-item"> 这个是没有select属性的<br /> <ng-content></ng-content> </div> <div class="content-item"> 这个是匹配标签的<br /> <ng-content select="h6"></ng-content> </div> <div class="content-item"> 这个是匹配css的<br /> <ng-content select=".demo"></ng-content> </div> <div class="content-item"> 这个是匹配属性的<br /> <ng-content select="[id=demo]"></ng-content> </div> </div> <!-- 这个是调用方 --> <demo-ng-content> <p>你说的对</p> <h6>这个是h6标签</h6> <div class="demo">我的class名称是demo</div> <div id='demo'>我有id=demo的属性</div> 结束 </demo-ng-content>下面是展示结果,有木有一目了然~ p标签和最后的文字这两块都替换了没有设置select属性的标签;
<h6></h6>标签替换了select="h6";<div class="demo">替换了select=".demo";<div id='demo'>替换了select="[id=demo]";我也是刚了解到这个标签,想到的比较好的应用场景:在样式和布局阶段,可以用这种方式实现,这样只需要维护一个样式,其他调用方就不用关注样式修改了~ 下面是自己写的个简单栗子:
<!-- 定义表单的公用样式布局 --> <main> <div class="item"> <div class="label"> <ng-content select=".item-label"></ng-content> </div> <div class="value"> <ng-content select=".item-value"></ng-content> </div> </div> </main> <!-- 调用公用布局,填充自己的表单 --> <main> <div class="body"> <demo-ng-content> <ng-container class="item-label">姓名:</ng-container> <input class="item-value" nz-input placeholder="请输入姓名"> </demo-ng-content> <demo-ng-content> <ng-container class="item-label">年龄:</ng-container> <input class="item-value" nz-input placeholder="请输入年龄"> </demo-ng-content> <demo-ng-content> <ng-container class="item-label">身份证:</ng-container> <input class="item-value" nz-input placeholder="请输入身份证号码"> </demo-ng-content> </div> </main>