当我在* ngFor中更改数组时,视图不会更新 [英] My view does not update when i change my array in *ngFor

查看:59
本文介绍了当我在* 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆