当我在* ngFor中更改数组时,视图不会更新 [英] My view does not update when i change my array in *ngFor
问题描述
我正在尝试创建一些内部带有mat-table的扩展面板,我的问题是我必须调整窗口大小才能更改视图.我的数据加载正常,但几乎所有视图都没有更新.我的扩展面板应该放置的位置只是空白.直到我单击一个按钮或调整窗口大小.什么会引起这样的事情?
I'm trying to create some expansion panels with mat-table's inside, my problem is i have to resize my windows before my view will change. My data is loading fine and all but somehow my view does not update. My view where my expansion panels should be, is just all blank. Untill i click a button or resize my window. What can cause something like this?
在我的ngOnInit()中,我致电
In my ngOnInit() i call
this.getSale1();
.HTML:
<mat-accordion>
<mat-expansion-panel *ngFor="let data of mySaleModelArray2 ">
<mat-expansion-panel-header>
<mat-panel-title>
<h6 class="salepanelheadtext">Bar:</h6>{{data.name}}
</mat-panel-title>
<mat-panel-description>
<h6 class="salepanelheadtext2">Total:</h6> {{data.total_sales}}
</mat-panel-description>
</mat-expansion-panel-header>
<div class="example-container mat-elevation-z8">
<mat-table #table [dataSource]="data.sales" >
<!-- PLU Column -->
<ng-container matColumnDef="pluNo">
<mat-header-cell *matHeaderCellDef >
#
</mat-header-cell>
<mat-cell *matCellDef="let salesdata">
{{salesdata.beerline}}
</mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let salesdata">
{{salesdata.pluName}}
</mat-cell>
</ng-container>
<!-- Sold_Count Column -->
<ng-container matColumnDef="sold_count">
<mat-header-cell *matHeaderCellDef>
QTY
</mat-header-cell>
<mat-cell *matCellDef="let salesdata">
{{salesdata.sold_count}}
</mat-cell>
</ng-container>
<!-- PLU Price Column -->
<ng-container matColumnDef="pluPrice">
<mat-header-cell *matHeaderCellDef> Price </mat-header-cell>
<mat-cell *matCellDef="let salesdata">
{{salesdata.pluPrice}}
</mat-cell>
</ng-container>
<!---->
<ng-container matColumnDef="total_amount">
<mat-header-cell *matHeaderCellDef>
Total
</mat-header-cell>
<mat-cell *matCellDef="let salesdata">
{{salesdata.pluPrice * salesdata.sold_count}}
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns2"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns2;"></mat-row>
</mat-table>
</div>
</mat-expansion-panel>
</mat-accordion>
.TS:
//Get data from Sale1List
getSale1() {
this.customersService.getSale1()
.subscribe(
dataList => {
this.updateDataTable(dataList);
}
)
}
updateDataTable(dataList) {
for(var i = 0;i < dataList.length; i++){
var saleData = <SaleDataModel>dataList[i];
var mySaleModelTest = this.mySaleModelArray2.find(x => x.name == dataList[i].name);
if(mySaleModelTest == null){
//first time creating the object with the bar name
var tempArray = Array();
tempArray.push(saleData);
this.mySaleModelArray2.push(new Sale1Model(dataList[i].name,dataList[i].pluPrice * dataList[i].sold_count,tempArray));
}else{
//changing the object with the bar name because it already exist
mySaleModelTest.total_sales = mySaleModelTest.total_sales + dataList[i].pluPrice * dataList[i].sold_count;
mySaleModelTest.sales.push(saleData);
}
}
}
推荐答案
ChangeDetectorRef
将解决问题.
将他注入构造函数中.
constructor(
...
private cdr: ChangeDetectorRef,
...
) { }
像这样
编辑 getSale1
以便使用cdr:
edit getSale1
like this in order to use the cdr:
getSale1() {
this.customersService.getSale1()
.subscribe(
dataList => {
this.updateDataTable(dataList);
this.cdr.detectChanges();
}
)
}
但是为什么我必须使用ChangeDetectorRef?
默认情况下,Angular使用 ChangeDetectionStrategy.default
,该代码使用其逻辑唤醒"渲染组件.此处提供更多规范: https://angular.io/api/core/ChangeDetectionStrategy
Angular, by default, use the ChangeDetectionStrategy.default
that use its logic to "wake-up" the component for the render. More spec here: https://angular.io/api/core/ChangeDetectionStrategy
在某些情况下,这还不够.一种情况可能是很大的嵌套 * ngFor
.
There are certain cases where this isn't enough. One case could be a very big nested *ngFor
.
那为什么要使用cdr?
正如我所说,在某些情况下Angular不会唤醒其渲染器.由于每种情况都不尽相同,因此不可能对此定义绝对的答案. cdr.detectChanges()
的作用是允许该方法通知Angular的渲染以强制其component.html的渲染.这样,无论您使用哪种 strategy
(即使它是 .onPush
),该组件都将重新呈现.
As I said, there are some cases when Angular does not wake up its renderer. Since every situation is not the same, it's quite impossibile to define an absolute answer to this. What cdr.detectChanges()
does, is to allow the method to inform the Angular's rendered to force the render of its component.html. In this way, no matter which strategy
are you using (even if it's .onPush
) the component will be re-rendered.
但是要小心.您必须先考虑自己在做什么,然后再执行此操作.例如,重新渲染html触发 ngOnChanges
事件.这样您就可以进入一个无限循环.
But be careful. you have to think what you are doing before implementing this. For example, re-render the html fire the ngOnChanges
event. So you could enter an endless loop.
有关cdr的更多信息: https://angular.io/api/core/ChangeDetectorRef
More info about cdr: https://angular.io/api/core/ChangeDetectorRef
希望这消除了一些疑问.
Hope that this cleared out some doubts.
这篇关于当我在* ngFor中更改数组时,视图不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!