Как использовать ngIf при вводе материала в дочернем компоненте без получения ExpressionChangedAfterItHasBeenCheckedError - PullRequest
0 голосов
/ 27 февраля 2019

Проблема

У меня есть PasswordComponent, в котором я хочу использовать ng-template. Однако теперь я получаю ошибку ExpressionChangedAfterItHasBeenCheckedError при редактировании пароля.Я хочу использовать errorStateMatcher только тогда, когда controlName === 'confirmPassword', и я не смог найти другой способ условно связать 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'.

Error Repro Steps

  • Введите что-то в поле пароля
  • Tab / нажмите на имя пользователя
  • Tab /вернуться к паролю
  • Введите или удалите символы, чтобы сообщение mat-error изменилось
  • В консоли вы увидите ExpressionChangedAfterItHasBeenCheckedError.

1 Ответ

0 голосов
/ 27 февраля 2019

Попробуйте следующее:

  <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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...