【问题标题】:Angular Material Stepper custom icons ng-template has undefined context variableAngular Material Stepper 自定义图标 ng-template 具有未定义的上下文变量
【发布时间】:2021-02-19 14:17:35
【问题描述】:

我正在尝试使用带有matStepperIcon 属性的ng-template 来覆盖默认的Angular Material 的matStepper 图标。我也想传递一些数据,我尝试使用ng-container*ngTemplateOutlet,但它只能部分工作。

从下面的代码中可以看出,我希望 print 函数始终打印定义的值,但是,在正确打印步骤的七个 ID 后,它会打印 undefined 七次。为什么会这样?如何防止这种情况发生?

<mat-horizontal-stepper labelPosition="bottom">
  <ng-container *ngFor="let step of form.steps">
    <ng-template #ref let-step="id" matStepperIcon="edit">
      <mat-icon>clear</mat-icon>
      {{ print(step) }}
    </ng-template>
    
    <ng-template #ref let-step="id" matStepperIcon="number">
      <mat-icon>clear</mat-icon>
      {{ print(step) }}
    </ng-template>

    <ng-template #ref let-step="id" matStepperIcon="done">
      <mat-icon>clear</mat-icon>
      {{ print(step) }}
    </ng-template>
    
    <ng-container *ngTemplateOutlet="ref; context: step"></ng-container>

    <mat-step>
      <ng-template matStepLabel>
        {{ step.id }}:
        {{ translateService.currentLang === "it" ? step.name : step.nameEn }}
      </ng-template>

      <!-- Step content-->
      </mat-step>
  </ng-container>
</mat-horizontal-stepper>

Link to StackBlitz example

另一方面,将我的代码更改为以下代码会导致 print 函数打印所有正确的 ID,但它也会打印最后一步的 ID 8 次。

<mat-horizontal-stepper labelPosition="bottom">
  <ng-container *ngFor="let step of form.steps">
    <ng-template #ref matStepperIcon="edit">
      {{ print(step.id) }}
      <mat-icon>clear</mat-icon>
    </ng-template>

    <ng-template #ref matStepperIcon="number">
      {{ print(step.id) }}
      <mat-icon>clear</mat-icon>
    </ng-template>

    <ng-template #ref matStepperIcon="done">
      {{ print(step.id) }}
      <mat-icon>clear</mat-icon>
    </ng-template>

    <ng-container *ngTemplateOutlet="ref; context: step"></ng-container>

    <mat-step>
      <ng-template matStepLabel>
        {{ step.id }}:
        {{ translateService.currentLang === "it" ? step.name : step.nameEn }}
      </ng-template>

      <!-- Step content-->
    </mat-step>
  </ng-container>
</mat-horizontal-stepper>

【问题讨论】:

    标签: angular ng-template mat-stepper angular-material-11


    【解决方案1】:

    如果你想在 MatStepper 中使用自定义图标,你应该做几件事:

    • 教图书馆考虑您的图标集。

    我们可以禁用displayDefaultIndicatorType 喜欢

    providers: [{
       provide: STEPPER_GLOBAL_OPTIONS, useValue: {displayDefaultIndicatorType: false}
    }]
    

    但这无济于事,因为 Angular Material 具有预定义的逻辑来根据内部步骤状态显示特定图标https://github.com/angular/components/blob/28c36f8a02f72e51a4d6c6a797e2f913e5dede9b/src/cdk/stepper/stepper.ts#L442-L465

    所以,您可以像这里 https://github.com/angular/components/issues/18307 那样覆盖基本逻辑

    @ViewChild(MatHorizontalStepper, { static: true }) stepper: MatHorizontalStepper;
    
    ngOnInit() {
      this.stepper._getIndicatorType = (i, state) => state || 'number';
    }
    
    • 根据步骤决定显示哪个图标

      <mat-step [state]="step.state">
      
      
      steps: [
        {
          id: 218,
          name: 'Dati richiedente',
          nameEn: 'Applicant data',
          state: 'home',
        },
        {
          id: 219,
          name: 'Richiesta Meeting',
          nameEn: 'Meeting request',
          state: 'edit'
        },
      
    • 使用内置的matStepperIcon 上下文访问渲染index。有了这个索引就可以访问对应的step

      <ng-template let-i="index" matStepperIcon="home">
        <mat-icon>home</mat-icon>
        {{ print(form.steps[i]) }}
      </ng-template>
      

    Forked Stackblitz

    【讨论】:

      【解决方案2】:

      我不确定为什么会这样,但您可以使用 bind 方法解决问题

      <ng-template  #ref let-step="id" matStepperIcon="number">
            <mat-icon>clear</mat-icon>
            {{ print.bind(step) }}
      </ng-template> 
      

      Working Example

      【讨论】:

        【解决方案3】:

        你的标记是错误的,我没有得到它应该是什么样子,但发现了 3 个错误:

        • 您不能有 3 个相同的模板引用。
        • 您还应该在 *ngFor 循环之外定义模板。
        • 最后 - 要向模板提供一些数据,您应该将其定义为具有 $implicit 键的对象。

        Here is stackblitz with changes

        【讨论】:

        • 您的解决方案似乎无法正常工作,因为它不会替换 mat-stepper 的默认图标。而是显示默认图标。三个ng-templates 必须在mat-horizontal-stepper 标签内。
        猜你喜欢
        • 2018-08-08
        • 2021-12-13
        • 2019-10-30
        • 2018-04-11
        • 1970-01-01
        • 1970-01-01
        • 2012-11-21
        • 2022-10-24
        • 1970-01-01
        相关资源
        最近更新 更多