1.ng-template
ng-template是一个模板元素,它永远不会自动渲染在视图上,在渲染视图之前,Angular 会把<ng-template>及其内容替换为一个注释,只有通过其他结构型指令(如 ng-if)或 template-ref 才能将模块内容渲染到页面中。TemplateRef对应ng-template的引用,
@Component({
selector: "app-root",
template: `
<ng-template>
<p class="test" (click)="test()">模板渲染测试</p>
</ng-template>
`,
})
export class AppComponent {
test(){}
}
运行上面这个例子,我们可以看到运行界面什么都没有显示出来,这是正常结果,也是预期结果,因为这里只是定义了,并还没有与其它结构型指令一起使用。
<div *ngIf="success else other">Successful</div>
<ng-template #other>
<div>Loading...</div>
</ng-template>
在上面这个例子中,我们首先判断了success这个变量是否为真,为真则显示Successful, else则渲染 #other的模板。当然除了*ngIf这个指令外,我们还可以结合ng-container
,ngFor
、ngClass
、ngStyle
和ngSwitch指令与模板元素一起使用。
let-* 属性是 ng-template 的一个特性,ng-template中通过 let 语法来声明绑定上下文对象属性名!它通过从上下文中获取变量的值来将变量注入到模板中。
<ng-template let-param let-data="text" let-name="name">
<span>{{param}}-{{data}}-{{name}}</span>
</ng-template>
let-param 取的是绑定对象context的$defaultValue字段的值,let-param相和let-param="$defaultValue"是等价; let-name="name" 取的是绑定对象context里面name字段对应的值 let-data="data" 取的是绑定对象context里面data字段对应的值
export class NgTemplateComponent {
context = {$defaultValue: '默认值', data: 'data值', name: 'lalala'};
}
2.ng-content
内容投影: Content Projection,用于创建可配置组件,这意味着可以根据用户的需要配置组件。下图是其本身的 HTML 定义:
<!-- 这是 test.html -->
<div class="box">
<div class="header">
这是头部
</div>
<div class="body">
<p>这是body部位</p>
</div
<div class="footer">
<ng-content></ng-content>
</div>
</div>
这样,footer 部分是允许动态配置内容,下面演示为 footer 区域动态配置内容。
<test>
<div>这是footer</div>
</test>
这种用法称为单一投射。我们直接使用上面图片中的selector:'test.html'进行内容的配置。
3.ng-container
ng-container
是一个逻辑容器,是 Angular
结构型指令中的一种,用于包含控制内部元素的显示与否。ng-container
可以包含任何元素,包括文本,但本身不会生成元素标签,也不会影响页面样式和布局。包含的内容,如果不通过其他指令控制,会直接渲染到页面中。
这个元素最常用在——>当我们需要同时使用*ngIf 和 *ngFor这两个指令的时候,因为我们如果把这两个指令同时放在一个div上,会出现报错,放在两个div上,就会有一个多余的div占据位置影响样式,所以我们经常会将*ngIf 和 *ngFor其中一个放在ng-container上面。
当我们在一个元素上使用 ngIf
和 ngFor
时:
<div *ngIf="test" *ngFor="let item of testArr">
<div class="lesson-detail">{{item}}</div>
</div>
这样并不能正常运行。只会得到以下错误:
Uncaught Error: Template parse errors:
Can't have multiple template bindings on one element. Use only one attribute
named 'template' or prefixed with *
报错的意思就是,不能在一个元素上同时使用两个结构性指令。所以为了解决这个问题我们会才用下面的形式:
<div *ngIf="test">
<div *ngFor="let item of testArr">
<div class="lesson-detail">{{item}}</div>
</div>
</div>
在这个例子中,不报错了但是很明显创建了一个多余的 div
。所以为了解决这个问题,我们会使用ng-container
指令。
<ng-container *ngIf="test">
<div *ngFor="let item of testArr">
<div>{{item}}</div>
</div>
</ng-container>
正如上面代码我们所能看到的,ng-container
指令提供了一个元素,而无需为此创建额外的元素。ng-container
指令还有另一个主要的用例:它还可以提供一个占位符来动态地将模板注入页面。比如下面这个示例:
<ng-container *ngIf="isTrue; then inner; else outter"></ng-container>
<ng-template #inner>
<div>
恭喜你成功进入系统.
</div>
</ng-template>
<ng-template #outter>
<div>
您已退出系统.
</div>
</ng-template>
对于ng-container标签,
还有一点也需要注意:书写在ng-container标签上面的样式类型可能不会生效,比如当你使用一个UI框架的一个表格组件的时候,需要结合使用:host deep修改这个表格组件的内部样式时,很明显,如果我们直接使用:host deep和表格标签,会同时修改了一个页面所有表格的样式,如果我们只想修改该页面的某个表格的样式呢?这个时候我们可以加一个范围。例如,我们将需要修改的表格放在<div class='special-table'></div>里面,在结合:host deep使用。此时特别注意,如果将表格放在<ng-container
class='special-table'></ng-container
>里面,则修改的样式不会生效,因为special-table这个样式类并没有在dom树上显示出来。
4.*ngTemplateOutlet
这个最常用来模板重用,考虑一个视图,您必须在多个位置插入模板。 例如,要放置在网站中的图标。 我们可以通过为图标编写一次模板并在视图中的任何地方重用它来实现它。
可以通过 ngTemplateOutlet
指令将模板本身实例化到页面上的任何地方,具体用法就是:通过模板引用语法 #loading
来引用 loading 模板,将 loading
赋值给 ngTemplateOutlet
结构指令,使其实例化模板。
<ng-template #loading> <div>Loading...</div> </ng-template>
<ng-container *ngTemplateOutlet="loading"></ng-container>
5.参考链接
https://blog.csdn.net/SeriousLose/article/details/121473680