【问题标题】:Angular ExpressionChangedAfterItHasBeenCheckedError with inline edit table带有内联编辑表的 Angular ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2018-05-29 19:02:44
【问题描述】:

我有一个表,它调用一个名为 modal 的子组件,modal 组件有两个按钮保存和取消,用于内联编辑。我知道我必须使用“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;

******************更新****************************** ******************************************************

浏览器仍然抛出 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, '') === "";
    }

【问题讨论】:

  • 我看到了这篇文章,我试着做 ngAfterViewInit() { this.cdr.detectChanges();它仍然不起作用,因为我设置的子输入不在 ngAfterViewInit 内。如果需要在“isEmpty”方法中设置子值,不知道该怎么做
  • 我使用了 setTimeout,它工作但很慢...我需要一个更好的解决方案

标签: angular typescript primeng


【解决方案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, '') === "";
}

【讨论】:

  • 我想我找到了一种方法来设置[disableEditSaveButton]的布尔值一次。因此,您不应该再次面对ExpressionChangedAfterItHasBeenCheckedError
  • 哇,它起作用了..非常简单但也很聪明......非常感谢..从你那里学到了一些有价值的东西:)
【解决方案2】:

试试这个方法:

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, '') === "";
}

【讨论】:

  • 已更新,我的代码..它正在工作,但在浏览器中它仍然抛出 ExpressionChangedAfterItHasBeenCheckedError。我宁愿通过在浏览器中不出现错误来解决这个问题,只是为了确保在我继续开发我的应用程序时这个错误不会导致其他问题,任何想法!
猜你喜欢
  • 2011-12-31
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多