ExpressionChangedAfterItHasBeenCheckedError в ngIf? - PullRequest
0 голосов
/ 19 июня 2020

Я не могу понять, что мне здесь не хватает.

SharedServiceA:

export class SharedServiceA {
    somethingWasUpdated = new Subject();

    updateSomething(value) {
        this.somethingWasUpdated.next(value);
    }
}

AnotherService:

export class AnotherService {
    doSomething() {
        this.sharedServiceA.updateSomething(true);
    }
}

component-a.component.ts

export class ComponentA {
    list = [];
    isShowList = false;

    ngOnInit() {
        this.sharedServiceA.somethingWasUpdated
            .pipe(takeUntil(this.destroyed))
            .subscribe(
                data => {
                    if (data) {
                        this.fetchData(); // Get data from another service, then populate list
                    }
                }
            );
    }
    
    fetchData() {
        // Get data from another service
        if (dataFound) {
            this.list = dataFound;
            this.isShowList = true;
        } else {
            this.isShowList = false;
        }
    }
}

component-a.component. html

<div *ngIf="!isShowList"> <!-- This is where ExpressionChangedAfterItHasBeenCheckedError points to: Previous value: 'ngIf: true'. Current value: 'ngIf: false' -->
    List empty
</div>
<div *ngIf="isShowList">
    Print something here
</div>

component-b.component. html

export class ComponentB {
    ngOnInit() {
        this.sharedServiceA.somethingWasUpdated
            .pipe(takeUntil(this.destroyed))
            .subscribe(
                data => {
                    if (data) {
                        // Get data from another service
                    }
                }
            );

        this.anotherService.doSomething(); // If I place this inside a setTimeout, I don't get the ExpressionChangedAfterItHasBeenCheckedError
    }
}

Это сценарий:

  1. Нажмите кнопку> ComponentA создается внутри вкладки

  2. Нажмите на другую кнопку> ComponentB создается внутри другой вкладки (в основном рядом с ComponentA)> ComponentA.fetchData()> ExpressionChangedAfterItHasBeenCheckedError

Почему я должен получить ExpressionChangedAfterItHasBeenCheckedError в ComponentA после того, как list был заполнен, а isShowList был установлен на true, и почему я не получаю сообщение об ошибке, если я поместите this.anotherService.doSomething(); внутри setTimeout?

Как этот код нарушает однонаправленный поток данных? Даже после прочтения нескольких статей я все еще сбит с толку в этом конкретном случае.

Ответы [ 2 ]

0 голосов
/ 20 июня 2020

Быстрая точка, ошибки ExpressionChangedAfterItHasBeenChecked видны только в режиме разработки. Не показывать в производственном режиме.

0 голосов
/ 19 июня 2020

В вашем компоненте используйте changeDectectorRef, как показано ниже:

    import { ChangeDetectorRef} from "@angular/core";

    constructor(private ref: ChangeDetectorRef){}

  fetchData() {
        // Get data from another service
        if (dataFound) {
            this.list = dataFound;
            this.isShowList = true;
        } else {
            this.isShowList = false;
        }
      this.ref.detectChanges();
    }

2-й метод

Если приведенное выше не работает для вас, используйте его в AfterViewChecked хуках жизненного цикла .

ngAfterViewChecked() {
     this.ref.detectChanges();
}

Надеюсь, это вам поможет !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...