如何解决Angular changeDetector.detectChanges打破* ngFor中的matTooltip
以下组件中的matTooltip正确变红。呈现了工具提示的叠加层和小气泡,但是缺少了文本(尽管在浏览器中进行检查时是在html中),并且位置不正确。
有趣的是,该工具提示在我删除detectChanges()调用时有效,或者即使在detectChanges();下也可以在* ngFor之外使用
@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 || []);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。