Angular Material 步进器自定义图标 ng-template 具有未定义的上下文变量
Angular Material Stepper custom icons ng-template has undefined context variable
我正在尝试使用 ng-template
和 matStepperIcon
属性 来覆盖默认的 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>
另一方面,将我的代码更改为以下内容会导致 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>
我不确定为什么会这样,但您可以使用绑定方法解决问题
<ng-template #ref let-step="id" matStepperIcon="number">
<mat-icon>clear</mat-icon>
{{ print.bind(step) }}
</ng-template>
你的标记是错误的,我不明白它应该如何,但发现了 3 个错误:
- 您不能有 3 个相同的模板引用。
- 你还应该在 *ngFor 循环之外定义你的模板。
- 最后 - 要向模板提供一些数据,您应该将其定义为具有 $implicit 键的对象。
如果你想在 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>
我正在尝试使用 ng-template
和 matStepperIcon
属性 来覆盖默认的 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>
另一方面,将我的代码更改为以下内容会导致 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>
我不确定为什么会这样,但您可以使用绑定方法解决问题
<ng-template #ref let-step="id" matStepperIcon="number">
<mat-icon>clear</mat-icon>
{{ print.bind(step) }}
</ng-template>
你的标记是错误的,我不明白它应该如何,但发现了 3 个错误:
- 您不能有 3 个相同的模板引用。
- 你还应该在 *ngFor 循环之外定义你的模板。
- 最后 - 要向模板提供一些数据,您应该将其定义为具有 $implicit 键的对象。
如果你想在 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>