具有内联编辑表的Angular ExpressionChangedAfterItHasBeenCheckedError

时间:2018-05-29 19:02:45

标签: angular typescript primeng

我有一个表调用一个叫做模态的子组件,模态组件有两个按钮保存和取消,用于内联编辑。我知道我必须使用" ChangeDetectorRef"但是我无法弄清楚如何使用这个事件" ngAfterViewInit"用我的代码

  

ExpressionChangedAfterItHasBeenCheckedError:表达式已更改   检查后。上一个值:' disableEditSaveButton:false'。   当前值:' disableEditSaveButton:true'。

dashboard.HTML

 <p-table #dt  [value]="iToDoList" dataKey="id"  [paginator]="true" [rowsPerPageOptions]="[10,50,100]"
                             [rows]="10">

                        <ng-template pTemplate="header">
                            <tr>
                                <th>ID</th>
                                <th>Comment</th>
                                <th>Action</th>

                            </tr>
                            </ng-template>
                            <ng-template pTemplate="body" let-row>  
                                <tr>
                                    <td>{{row.id}}</td>
                                    <td>
                                        <div  *ngIf="!row.isEditable">{{row.comment}}</div>
                                        <div *ngIf="row.isEditable">
                                            <input type="text" [(ngModel)]="row.comment">
                                            <span *ngIf="isEmpty(row.comment)" style="color:crimson">Required</span>
                                        </div>
                                    </td>
                                    <td>
                                        <div>
                                            <modal  [disableEditSaveButton]='disableSaveButton' (open)="onOpen(row)" [showModal]="!row.isEditable"  (selectedRow)="onSelectedRow(row)" (cancelEdit)="onCancelEdit(row)"></modal>
                                        </div>
                                        <!--<button (click)="editRow(row)">Edit</button>-->
                                    </td>
                                    <td>                                <button (click)="save(row)">Save</button></td>
                                </tr>
                            </ng-template>

                    </p-table>

dashboard.compnent (这导致ExpressionChangedAfterItHasBeenCheckedError)

 isEmpty(input) {
        if (input.replace(/\s/g, '') === "") {

            this.disableSaveButton = true;
        }
        else {
            this.disableSaveButton = false;
       }
       // this.cdr.detectChanges();

        return input.replace(/\s/g, '') === "";
    }

modal.html

   <div *ngIf='!showModal'>
        <button type="button" class="btn-xs btn-primary" (click)="onSave()" [disabled]='disableEditSaveButton'>Save</button>
        <button type="button" class="btn-xs btn-orange" (click)="onCancelEdit()">Cancel</button>
    </div>

modal.component

@Input() disableEditSaveButton: boolean = false;

****************** UPDATE **************************** **************

浏览器仍在抛出ExpressionChangedAfterItHasBeenCheckedError

组件

   isEmpty(input) {

        this.cdr.detach();

        if (input.replace(/\s/g, '') === "") {

            this.disableSaveButton = true;
        }
        else {
            this.disableSaveButton = false;
        }
        // this.cdr.detectChanges();

        // restart change detection for this view
        this.cdr.reattach();

        return input.replace(/\s/g, '') === "";
    }

2 个答案:

答案 0 :(得分:1)

好的,这是另一种方法。

分析你的代码我可以看到

this.disableSaveButton === isEmpty(row.comment)

这意味着,如果isEmpty(row.comment)为真,this.disableSaveButton也是如此,反之亦然。

那么为什么不直接使用isEmpty(row.comment)的结果而不是将其存储到this.disableSaveButton?这样做你没有改变表达式,因为第一个true或false也将是最后一个。

请以这种方式试试:

<modal  [disableEditSaveButton]='isEmpty(row.comment)' 
        (open)="onOpen(row)" 
        [showModal]="!row.isEditable"  
        (selectedRow)="onSelectedRow(row)" 
        (cancelEdit)="onCancelEdit(row)">
</modal>

如果你不需要this.disableSaveButton用于其他目的而不是你的模态对话,这意味着你现在根本不需要它,你可以缩小你的方法的大小,而不改变它的逻辑结果

isEmpty(input) {
    return input.replace(/\s/g, '') === "";
}

答案 1 :(得分:0)

以这种方式尝试:

isEmpty(input) {
    // stop change detection for this view
    this.cdr.detach(); 

    if (input.replace(/\s/g, '') === "") {

        this.disableSaveButton = true;
    }
    else {
        this.disableSaveButton = false;
   }
   // this.cdr.detectChanges();

    // restart change detection for this view
    this.cdr.reattach(); 

    return input.replace(/\s/g, '') === "";
}