角度变化Detector.detectChanges()在*ngFor中中断matTooltip



以下组件中的matTooltip正在正确地重新调用。工具提示的覆盖和小气泡会被渲染,但文本丢失(尽管在浏览器中检查时在html中(,并且位置不正确。

有趣的是,当我删除detectChanges((调用时,工具提示会起作用,或者它在*ngFor之外起作用,即使使用detectChanges((;

@Component({
selector: 'mur-app-titlebar',
templateUrl: './app-titlebar.component.html',
styleUrls: ['./app-titlebar.component.scss']
})
export class AppTitlebarComponent implements OnInit, OnDestroy {
public appbarItems: IMenuItem[];
private destroy$ = new Subject();
constructor(
private appBarService: AppBarService, // my custom service
private changeDetector: ChangeDetectorRef,
) {
}
public ngOnInit() {
this.appBarService.getAppbarItems().pipe( //observable comes from outside of angular
takeUntil(this.destroy$)
).subscribe(value => {
this.appbarItems = value || [];
// change detection is not triggered automatically when the value is emmited
this.changeDetector.detectChanges(); 
});
}
public ngOnDestroy() {
this.destroy$.next();
}
}
<ng-container *ngFor="let item of appbarItems">
<button mat-button
(click)="item.onclick && item.onclick()"
[disabled]="item.disabled"
[matTooltip]="item.tooltip"
[style.color]="item.color">
<mat-icon *ngIf="item.icon"
[class.mr-3]="item.label">
{{item.icon}}
</mat-icon>
<span>{{item.label}}</span>
</button>

</ng-container>

我已经验证过,appbarItems只设置了一次,并且没有更改

通常在Angular中异步操作的回调中不需要调用cdRef.detectChanges()

但如果你这样做,就意味着你正试图解决视图更新的一些问题。异步代码后组件视图不更新的原因可能有几个:

  • 您的组件在OnPush更改检测策略下被隐藏以进行检查

  • 回调在Angular区域之外执行。

看起来你遇到了第二种情况。在Angular区域之外调用cdRef.detectChanges将导致某些Angular处理程序将在Angular区之外注册的情况。因此,这些处理程序不会更新视图,您将在其他地方调用detectChanges,或者再次使用zone.run.

下面是这样一个例子https://ng-run.com/edit/XxjFjMXykUqRUC0irjXD?open=app%2Fapp.component.ts

您的解决方案可能是使用ngZone.run方法将代码执行返回到Angular区域:

import { NgZone } from '@angular/core';
constructor(private ngZone: NgZone) {}
.subscribe(value => {
this.ngZone.run(() => this.appbarItems = value || []);

最新更新