如何在子组件的材料输入中使用ngIf而不获取ExpressionChangedAfterItHasBeenCheckedError

时间:2019-02-26 22:37:25

标签: javascript angular typescript angular-material

问题

我有一个要使用PasswordComponent的{​​{1}}。但是,现在在编辑密码时出现ng-template错误。我只想在ExpressionChangedAfterItHasBeenCheckedError时使用errorStateMatcher,却找不到其他有条件绑定controlName === 'confirmPassword'

的方法。

可以看到here的完整代码,在errorMatcher内,您会发现引起问题的password.component.html

ng-template
  

注意:即使您删除了 <template *ngIf="controlName === 'confirmPassword'; then Custom else Default"></template> <ng-template #Custom> <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/> </ng-template> <ng-template #Default> <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/> </ng-template> 并将ng-template直接放在ngIf上,错误仍然显示。我最初认为问题出在input,但实际上是ng-template

错误

ngIf的数字各不相同,有时值为mat-error

aria-describedby: null

错误再现步骤

  • 在密码字段中输入一些内容
  • 标签/点击返回用户名
  • 选择/点击返回密码
  • 键入或删除字符,以使PasswordComponent.html:4 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'aria-describedby: mat-error-3'. Current value: 'aria-describedby: mat-error-4'. 消息更改
  • 您将在控制台中看到一个mat-error

1 个答案:

答案 0 :(得分:0)

尝试以下操作:

  <input #Custom *ngIf="controlName === 'confirmPassword'; else Default" matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>

<ng-template #Default> 
        <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/> 
    </ng-template>

编辑

简而言之,它可能归结为使用父值的子模板,该子值在渲染子项之后已被修改。这通常是在父级完成渲染之前渲染子级时发生的。最初,我认为这是因为您将errorStateMatcher指令放在子模板中。

请参阅以下文章,因为它比我能更好地解释了该问题,并且还介绍了一些导致该问题的常见模式以及如何进行更改以解决该问题:

https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

编辑

在您的评论之后,可能是ngIf指令与matInput指令冲突。您可以尝试以下方法吗?

<ng-container *ngIf="controlName === 'confirmPassword'; else Default">
    <input #Custom matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
</ng-container>
<ng-template #Default> 
    <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/> 
</ng-template>

以下是一个可行的示例:StackBlitz Example