ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“未定义”异常
Posted
技术标签:
【中文标题】ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“未定义”异常【英文标题】:ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined' Exception 【发布时间】:2020-06-16 09:01:54 【问题描述】:我知道这个问题已经被问过很多次了,但是在阅读了类似的问题之后,我仍然无法组织我的代码来修复这个异常,
在我的组件中,我有这个根据条件动态变化的属性
public emailToValue: string
在我的html中
用户可以手动添加一个新行,然后我调用一个管道来设置组件中分配的值
<ng-container matColumnDef="emailTo">
<mat-header-cell *matHeaderCellDef mat-sort-header>Email To</mat-header-cell>
<mat-cell *matCellDef="let userMarket">
userMarket | formatEmailTo : emailToValue
<input type="text" matInput [value]="userMarket.emailTo">
</mat-cell>
</ng-container>
这是我的管道,如果电子邮件为 null 或未定义,我默认设置一个电子邮件以显示在新行中
@Pipe(
name: 'formatEmailTo',
)
export class FormatEmailPipe implements PipeTransform
public transform(userMarket: UserMarketDTO, email: string): void
if (_.isNil(userMarket.emailTo))
userMarket.emailTo = email;
功能正常,但每次创建新行时都会出现此异常
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'value: undefined'. Current value: 'value: suport@support.com'.
我会很感激任何帮助
谢谢
【问题讨论】:
【参考方案1】:这里有几点:
-
功能仅在更改检测运行两次的开发模式下工作。当您收到该错误时,这意味着
undefined
的第一个值将是生产中前端的值。
我不确定这是管道的最佳用途。我通常希望管道能够实际转换并返回 HTML 需要的值。对我来说,听起来您应该在添加行时默认您的电子邮件值。
但假设有一些要求迫使您这样做,并且您想避免使用 ChangeDetectorRef,我想我有一个解决方案给您。请看我的stackblitz:
使用template ref 用于已通过管道传输的UserMarketDTO
的列:
<ng-template #emailCell let-userMarket>
userMarket.email
<input type="text" matInput [value]="userMarket.email">
<ng-template>
以及管道发生的列定义:
<!-- Email Column -->
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef> Email </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngTemplateOutlet="emailCell; context: $implicit: element | formatEmailTo: defaultEmailValue "></ng-container>
</td>
</ng-container>
但这也需要更新管道以返回UserMarketDTO
:
public transform(userMarket: UserMarketDTO, defaultEmail: string): UserMarketDTO
if (!userMarket.email)
userMarket.email = defaultEmail;
return userMarket;
【讨论】:
以上是关于ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“未定义”异常的主要内容,如果未能解决你的问题,请参考以下文章