簡體   English   中英

Angular 4:`ExpressionChangedAfterItHasBeenCheckedError:表達式在檢查后發生了變化

[英]Angular 4: `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked

我的子模塊中的每個EventEmiiter都會出現此錯誤,但我無法找到解決方法。

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.

這是觸發我的EventEmitter的原因:

ngOnChanges(changes: any) {
    if (changes.groupingTabValid) {
        if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue) {
            this.groupingTabValidChange.emit(this.groupingTabValid);
        }
    }
}

這是我的“主要”組件的HTML

<year-overview-grouping [definitionDetails]="definitionDetails"
                        [fixedData]="fixedData"
                        [showValidation]="showValidation"
                        [groupingTabValid]="groupingTabValid"
                        (groupingTabValidChange)="setValidators('groupingTab', $event)">

</year-overview-grouping>

哪個叫這個功能

public setValidators(validator: string, e: boolean) {
    switch (validator) {
        case "groupingTab":             
            this.groupingTabValid = e;
            break;

        case "selectionTab":
            this.selectionTabValid = e;
            break;
    }

    if (this.groupingTabValid && this.selectionTabValid) {
        this.valid = true;
    } else {
        this.valid = false;
    }
}

1)在一個簡單的解釋中,是什么導致了這個錯誤?

2)我可以采取哪些措施來解決這個問題?

遵守單向數據流規則

嘗試使用setTimeout將調用推遲一個tick

if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue) {
    setTimeout(() => this.groupingTabValidChange.emit(this.groupingTabValid), 0)
}

只需導入ChangeDetectionStrategy,然后將其添加到組件中

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'app-bla-bla-bla',
  templateUrl: './xxxxx'
})

您可以避免使用setTimeout並告訴Angular在初始檢查后即將發生更改。

你可以注入ChangeDetectorRef到您的組件,並使用其markForCheck方法。

/* ... */

constructor(private cdr: ChangeDetectorRef) {}

/* ... */

if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue {
  this.cdr.markForCheck();
  this.groupingTabValidChange.emit(this.groupingTabValid);
}

我自己剛開始看這個異常類型,所以沒有專家,但假設它是在那里停止反饋循環。

我看不出任何明顯的原因,你想要將值發送給孩子並備份到父,但假設孩子應用了一些額外的邏輯。 對我來說,在服務而不是子組件中應用任何其他邏輯似乎更好。

我意識到plunker代碼沒有循環,但Angular機制似乎相當簡單 - 只需在循環結束時重新檢查值。 請注意,您的問題代碼中的groupingTabValid會直接反饋。

查看給定的plunker代碼,從結構上可以在父級上處理對年齡的更改。 click事件將是(click)=changeAge(age.value)和方法(在父級上)來處理它

changeAge(inputAge) {
  this.newAge = inputAge;
  this.person.age = inputAge;
}

這是一個掠奪者的叉子。 改良的plunker
子組件仍然更新person.age,但不再導致錯誤,因為該值與父項上設置的值相同。

我有同樣的問題。 為了解決這個問題,我做了這個小小的黑客。

setTimeout((()=>this.valueSelect.emit(idChange)), 0);

其中“this.valueSelect.emit(idChange)”是我將發出的變化

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM