简体   繁体   中英

Error setting width - Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked

I use a kendo-grid to display some data. I use [width] property to dynamically apply the desired width to each column. I have a columnsWidths: Array<{ field: string, width: number }> to achieve the result.

html

<kendo-grid-column field="Title" title="{{lbl_ColTitle}}" [hidden]="isHidden('Title')" [width]="isWidth('Title')" class="editableGridCell" [editable]="!APsService.isLoading && isPendingDocument && isGDPRApproved && !isTemplate && isAllowedToUpdate">
     <ng-template kendoGridCellTemplate let-dataItem>
         {{dataItem.Title}}
     </ng-template>
</kendo-grid-column>
<kendo-grid-column field="Description" title="{{lbl_ColDescription}}" [hidden]="isHidden('Description')" [width]="isWidth('Description')" class="editableGridCell" [editable]="!APsService.isLoading && isPendingDocument && isGDPRApproved && !isTemplate && isAllowedToUpdate">
     <ng-template kendoGridCellTemplate let-dataItem>
         {{dataItem.Description}}
     </ng-template>
</kendo-grid-column>

ts

public isWidth(columnName: string): number {
    return this.columnsWidths.findIndex((item: any) => item.field === columnName) > -1 && this.columnsWidths.filter((item: any) => item.field === columnName)[0].width;   
}

Everything looks great using the code above. However, I would like to slightly modify the width in a specific case (when a column's width is greater than the available grid width). So, I've changed my code to:

public isWidth(columnName: string): number {
    if (this.columnsWidths.filter((item: any) => item.width >= this.gridView.wrapper.nativeElement.offsetWidth).length > 0) {         
        return this.columnsWidths.findIndex((item: any) => item.field === columnName) > -1 && this.columnsWidths.filter((item: any) => item.field === columnName)[0].width * 0.7;
    }
    else {
        return this.columnsWidths.findIndex((item: any) => item.field === columnName) > -1 && this.columnsWidths.filter((item: any) => item.field === columnName)[0].width;
    }
}

The actual result displayed is the right one (column widths seem to be applied correctly), but the following error comes up in my console:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'width: 641.1999999999999'. Current value: 'width: 916'.

I did try to console.log to find out what's going on in the isWidth method and found out that the first condition is initially met (it shouldn't as the saved setting is {field: "Description", width: 916} and the gridView.wrapper.nativeElement.offsetWidth is 1830) and, after that, the second one is continuously met (as expected).

How can I avoid this error? Thank you.

I tried to find a solution reading a lot of stuff from many sources. Trying several workarounds, I found out that the solution in my case is the following:

ngAfterViewInit() {
    this.ref.detectChanges(); <--- this is the only code I added 
    setTimeout(() => {
        this.calcPageSize();
    });
    window.addEventListener('resize', this.calcPageSizeOnResize);
}

However, using concole.log I realized that it behaves in the same way. The first condition is initially met and, after that, the second one is met for the rest of the component's life. The difference is that the error disappeared from my console output.

I hope there is no bad effect occurring from this addition and nothing else changes in an undesired way.

This helped me a lot https://stackoverflow.com/a/52922389/9880356 and here you can find a really useful source: https://medium.com/angular-in-depth/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM