首页 > 解决方案 > 动态分配值给 matTooltip 时的 ExpressionChangedAfterItHasBeenCheckedError

问题描述

动态分配值时出现matTooltip此错误ExpressionChangedAfterItHasBeenCheckedError
我尝试使用它来修复它,detectChanges()但后来我收到了这个错误Maximum call stack size exceeded

要求:我需要在文本被截断时显示工具提示。

html

<div class="container">
  <p *ngFor="let each of tooltipsData" #element [matTooltip]="isTextTruncated(element) ? each : null">{{each}}</p>
</div>

打字稿

tooltipsData = [
 "Lorem Ipsum",
 "Lorem Ipsum is simply dummy text",
 "Lorem",
 "Lorem Ipsum is simply dummy text of the printing and typesetting"
];

isTextTruncated(element: any) {
 // this.cdr.detectChanges();
 return element.scrollWidth > element.clientWidth;
}

Stackblitz 示例

标签: angularangular-material

解决方案


TL;DRdetectChanges() -呼入ngAfterViewInit()

例子

import { Component, AfterViewInit, ChangeDetectorRef } from '@angular/core';
...
constructor(private cdr: ChangeDetectorRef) { }
...
ngAfterViewInit() {
 this.cdr.detectChanges();
}

解释

Angular 运行从to开始的生命周期钩子列表。在此过程中,角度存储先前的值并与当前值进行比较(例如,In when is和 in is ),如果在运行时更改值,则会发生此错误ngOnInitngAfterViewInitngOnInitxfalsengAfterViewInit xtruelifecycle hooksExpression...Previous value: 'message: false'. Current value: 'message: true'.

我的场景

我正在显示基于 DOM 操作的工具提示(当文本被截断时),所以在ngOnInitDOM 中没有加载任何元素,所以最初的值是null并且在ngAfterViewInit元素被加载并且工具提示值从更改nullLorem Ipsum is simply dummy text所以我们需要告诉 angular 来检测 ngAfterViewInit.

其他场景 异步 API

更新

上述解决方案在示例 stackblitz中有效,但在我真正的 Angular 项目中它不起作用,因为我从Async API获得了工具提示值。

所以我detectChanges()在API完成后调用。


推荐阅读