我需要动态渲染 Accordion 内的扩展面板列表。
标记非常简单:
<mat-accordion *ngIf="currentVenue">
<mat-expansion-panel *ngFor="let gig of currentVenue.gigs" expanded="false">
<mat-expansion-panel-header>
<mat-panel-title>
{{gig.name}}
</mat-panel-title>
<mat-panel-description>
Type your name and age
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>
不幸的是,这会导致控件无法使用。标题没有打开面板,整个 Accordion 功能也很困惑。我需要单击控件外部,然后随机打开一个子扩展面板(或不打开)。
如果我反过来使用“静态”方法(我从示例代码中复制了此方法),一切都会按预期进行:
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Personal data
</mat-panel-title>
<mat-panel-description>
Type your name and age
</mat-panel-description>
</mat-expansion-panel-header>
<mat-form-field>
<input matInput placeholder="First name">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Age">
</mat-form-field>
</mat-expansion-panel>
[...]
</mat-accordion>
我的猜测是,它与 *ngIf 以及控件的创建方式有关。
我正在使用 Angular Material 6.4.7 和 Angular 6.1.10
请您参考如下方法:
你对 *ngIf 在这里做了一些有趣的事情是正确的。它是一个结构指令,因此在较低级别上,Angular 的渲染方式与其他组件不同。这种渲染可能会干扰其他结构指令,因此 Angular 只允许模板一次绑定(bind)到一个结构指令。
但是好消息!名称中的星号只是结构指令真正作用的语法糖。如果我们对名称进行去糖处理并将其显式绑定(bind)到模板, 包围 Accordion 本身,Angular 将能够使用此模板上下文渲染嵌套指令,而不是使用组件的模板:
<ng-template [ngIf]="currentVenue">
<mat-accordion>
<mat-expansion-panel *ngFor="let gig of currentVenue.gigs" expanded="false">
<mat-expansion-panel-header>
<mat-panel-title>
{{gig.name}}
</mat-panel-title>
<mat-panel-description>
Type your name and age
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>
</ng-template>
请注意 ngIf 现在如何像常规指令一样绑定(bind)。这只能用在 ng-template 标签上。如果没有星号,Angular 将不会尝试将不同的模板绑定(bind)到它,并且嵌套指令将起作用。
我们还可以为重复项提供自己的 ng-template 和 ngForOf 指令,但是 [ngIf] 的语法更加清晰.

