Skip to main content
 首页 » 编程设计

angular中动态渲染的垫扩展面板未按预期工作

2026年04月06日45mfrbuaa

我需要动态渲染 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-templatengForOf 指令,但是 [ngIf] 的语法更加清晰.