我在读关于*ngTemplateOutlet指令的文章。此指令的使用是通过模板引用和上下文对象作为参数动态实例化模板。
我想知道的是,为了实现与*ngTemplateOutlet相同的结果,我们有太多的东西是有角度的,例如:
*ngIf,它可以根据同一组件中的组件变量值呈现不同的模板。以类似的方式,我们有[ngSwitch],它将根据不同的值为我们呈现不同的模板。*ngIf中使用引用。对于前一种情况:
<div *ngIf="condition1"> Content 1 </div>
<div *ngIf="condition2"> Content 2 </div>
<div *ngIf="condition3"> Content 3 </div>对于后者:
<ng-container *ngIf="condition then myTemplate else otherTemplate"></ng-container>
<ng-template #myTemplate> Some content... </ng-template>
<ng-template #otherTemplate> Some content... </ng-template>如果我们的武库中有这样的方法,那么*ngTemplateOutlet还能增加什么价值呢?
有什么实际的用例(如果有的话),我们不能使用上面的方法,应该使用*ngTemplateOutlet指令,或者它只是另一种方法来实现相同的结果?
发布于 2018-10-20 22:52:04
角模板出口可用于在视图的不同部分插入公共模板,这些部分不是由循环生成的,也不是受条件约束的。例如,您可以为公司的徽标定义一个模板,并将其插入页面中的几个位置:
<div>
<ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
<h1>Company History</h1>
<div>{{companyHistory}}</div>
</div>
<form (ngSubmit)="onSubmit()">
<ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
<h1>User info</h1>
<label>Name:</label><input type="text" [(ngModel)]="userName" />
<label>Account ID:</label><input type="text" [(ngModel)]="accountId" />
<button>Submit</button>
</form>
<div class="footer">
<ng-container *ngTemplateOutlet="companyLogoTemplate"></ng-container>
</div>
<ng-template #companyLogoTemplate>
<div class="companyLogo">
<img [src]="logoSourceUrl">
<label>The ACME company, {{employeeCount}} people working for you!</label>
</div>
</ng-template>模板和模板插座也可以帮助使组件可配置。下面的示例取自这篇文章 by 角大学。
选项卡容器组件定义默认选项卡标头模板,但允许使用定义为输入属性的自定义模板覆盖它。然后使用模板出口将适当的模板(默认或自定义)插入到视图中:
@Component({
selector: 'tab-container',
template: `
<ng-template #defaultTabButtons>
<div class="default-tab-buttons">
...
</div>
</ng-template>
<ng-container *ngTemplateOutlet="headerTemplate || defaultTabButtons"></ng-container>
... rest of tab container component ...
`
})
export class TabContainerComponent {
@Input() headerTemplate: TemplateRef<any>; // Custom template provided by parent
}在父组件中,定义自定义选项卡标头模板并将其传递给选项卡容器组件:
@Component({
selector: 'app-root',
template: `
<ng-template #customTabButtons>
<div class="custom-class">
<button class="tab-button" (click)="login()">
{{loginText}}
</button>
<button class="tab-button" (click)="signUp()">
{{signUpText}}
</button>
</div>
</ng-template>
<tab-container [headerTemplate]="customTabButtons"></tab-container>
`
})
export class AppComponent implements OnInit {
...
}您可以在这篇博客文章中通过alligator.io看到另一个高级用例。
发布于 2019-08-20 20:13:34
使*ngTemplateOutlet比*ng-content更强大的一点是,当您将它与ngTemplateOutletContext输入一起使用时。这使您能够创建一个完全唯一的模板,该模板可以在组件中使用状态。
我使用它创建了一个select组件,该组件通过不同的模板为每个客户端独特的样式,但共享完全相同的代码。这是一个StackBlitz链路,也是我在indepth.dev上的文章。
*ngTemplateOutlets比使用*ngIfs更有好处的一个例子是,如果您的组件仅供单个客户端使用,那么您的组件不需要依赖外部包,即Icon lib。
发布于 2018-10-20 19:20:36
你的问题很有道理。如果通过简单的if或switch情况可以实现某件事情,我们为什么要使用*ngTemplateOutlet?
独立分量
您之所以得到这些想法,是因为您正在考虑一个独立的组件级别。换句话说,所有条件,模板都在同一个组件中。根据一定的条件,可以方便地选择模板。
库组件
动态模板
当我说库组件时,它意味着通用可重用组件ex Autocompleter或Typeahead等。这些组件提供了功能部分,但是它们允许开发人员根据自己的需要选择自己的template。
现在的问题是,这些模板不是驻留在Autocompleter上,而是来自于它的@ContentChild。
例:
<ng-autocompleter>
<ng-template #item let-item>{{item.name}}</ng-template>
<ng-autocompleter>在上面的示例中,<ng-template>被定义为开发人员稍后的时间,而不是<ng-autocompleter>的直接部分。
模板上下文
在开发高度配置的组件时,模板上下文非常重要。获取动态模板(html)不足以达到目的。我们需要将值绑定到ng-template。由于ng-模板不在ng-autocompleter的一部分,所以我们需要传递包含所有要绑定的数据的上下文。
例:在上述情况下,如果您看到,我们通过item声明了let-item变量,但是item是从哪里来的。这将由提供给*ngTemplateOutlet的上下文决定。
有一行结论,如果我们想注入模板,这将在将来由某人声明,我不能处理这个案例*ngIf或*ngSwitch。我们需要使用
*ngTemplateOutlet。
https://stackoverflow.com/questions/52908844
复制相似问题