我的一个组件出现了奇怪的行为。组件从中的服务加载对象列表 ngOInit()
. 我面临的问题是完全随机的,有时需要花费大量时间来呈现此列表,有时是即时的。我已经排除了这是一个后端问题,调用后端总是很快。我发现了以下几点。加上钩子之后 DoCheck
我已经看到,当提到的问题发生时,它需要相当长的一段时间,因为 ngOnInit()
到达终点和终点 ngDoCheck()
被称为。
根据angular的文件 ngDoCheck()
被召唤 ngOnIni()
所以我不完全理解为什么有时候需要这么长时间。我补充说 console.log
每次调用的执行时间——我在调用的最后一行添加了日志 ngOnInit()
,当获取对象列表的调用实际完成时 ngDoCheck()
.
这就是浏览器控制台在花费大量时间时的外观:
正如你所看到的,它已经完成了任务 ngOnInit()
,然后完成 ngDoCheck()
,完成获取项目,然后在10秒后运行 ngDoCheck()
当列表在屏幕中实际呈现时。
这是组件代码的一部分 ngOnInit()
及 ngDoCheck()
:
ngDoCheck(){
console.log('ngDoCheck. N. Items ' + this.items.length, new Date());
}
ngOnInit() {
this.isLoading = true;
this.sensorTypeConfigEndpoint.getInheritedType().then(result => {
this.typeInherited = result;
if (this._markers) {
const groups = this._markers.map(marker => marker.get('group'));
if (groups && groups.length) {
this.getItemsByMapVisualization(this.typeViewMap, _.cloneDeep(groups)).then( items => {
this.items = items;
console.log('items N. Items ' + this.items.length, new Date())
this.isLoading = false;
});
}
}
});
console.log('ngOnInit N. Items ' + this.items.length, new Date())
}
这是html:
<div class="flex-cards" [ngStyle]="{'max-height': maxHeight}" [class.columnWrap]="isClusterInside" [appLoading]="isLoading">
<div (click)="expand()" *ngIf="isClusterInside" class="grid-expand">
<img class="filter-grey" src="assets/images/expand_cluster.svg" alt="Expand" style="width: 100%; height: 100%;margin-left: 4px">
<p class="text-expand" style="margin-bottom: 10px">
Expandir
</p>
</div>
<section class="card" style="height: calc(100% - 12px); overflow-y: auto;">
<div class="content-card">
<div *ngFor="let item of items">
{{item.text}}
</div>
</div>
</section>
</div>
你知道为什么要花这么长时间才能呈现这个列表吗?这是随机发生的。
2条答案
按热度按时间aoyhnmkz1#
注意
ngDoCheck
在可能影响组件的更改检测周期中运行。所以它会在之后运行一次ngOnInit
然后又被其他东西调用(也许是鼠标移动?在什么东西上盘旋?点击如果没有stackblitz复制您的问题,很难说是肯定的,但它似乎不是从您对服务的异步调用内部强制执行的。如果未触发更改检测,则不会更新dom,因此您将看不到组件。您也没有向我们展示您使用的更改检测策略,并且您在模板中使用的一些属性也会影响组件的布局,从而导致问题。尝试使用changedetectorref手动强制检查
isLoading = false
代码的一部分。这将帮助您确定这是变更检测问题还是其他问题。如果它开始工作,我建议在官方文档中阅读更多关于变更检测和Angular 生命周期的内容,以了解如何解决这个问题——我不会比他们做得更好:)but5z9lq2#
sensorTypeConfigEndpoint
看起来像是“天使世界之外”的东西。当它对this.items
及this.isLoading
,angular没有意识到这一点,也没有重新绘制视图。这就像angular在睡觉,因为它看不到任何变化。
ngDoCheck()
一种“唤醒”Angular ,并强制它考虑更改并重新绘制视图,但唤醒是一种副作用,它只允许您人工触发重新绘制。为了正确触发重画,请使用
ngZone
: