programing

Angular 4 표현식이 확인된 후 변경됨 오류

magicmemo 2023. 6. 30. 22:15
반응형

Angular 4 표현식이 확인된 후 변경됨 오류

상위 구성 요소 =>

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: ''. Current value: '[object Object]'.
            at viewDebugError (vendor.bundle.js:8962)
            at expressionChangedAfterItHasBeenCheckedError (vendor.bundle.js:8940)

상위 구성 요소 Html

<div>
  <app-child-widget [allItems]="allItems" (notify)="eventCalled($event)"></app-child-widget>
<div>

상위 구성 요소

export class ParentComponent implements OnInit {

  returnedItems: Array<any> = [];
  allItems: Array<any> = [];

  constructor(
  ) { }

  ngOnInit() {
     this.allItems = // load from server...
  }

  eventCalled(items: Array<any>): void {
    this.returnedItems = items;
  }
}

하위 구성 요소

@Component({
  selector: 'app-child-widget',
  templateUrl: 'child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Output() notify: EventEmitter<any> = new EventEmitter();
  @Input() private allItems: Array<any>;

  constructor() { }

  ngOnInit() {
    doSomething();
  }

  doSomething() {
    this.notify.emit(allItems);
  }
}

오류에 대해 알아야모든 내용은 이 동작을 매우 자세히 설명합니다.

원인

문제는 이 문제와 매우 유사하지만 서비스를 통해 상위 속성을 업데이트하는 대신 동기식 이벤트 브로드캐스트를 통해 업데이트합니다.다음은 링크된 답변의 인용문입니다.

다이제스트 사이클 동안 Angular는 하위 디렉티브에 대해 특정 작업을 수행합니다.이러한 작업 중 하나는 입력을 업데이트하고 하위 지침/구성 요소에서 ngOnInit 라이프사이클 후크를 호출하는 것입니다.중요한 것은 이러한 작업이 엄격한 순서로 수행된다는 것입니다.

  • 입력 업데이트
  • 호출 초기화

그래서 당신의 경우 Angular 업데이트된 입력 바인딩.allItems하위 구성 요소에서, 그런 다음 호출onInit업데이트를 유발한 하위 구성 요소에 대해allItems상위 구성 요소의.이제 데이터 불일치가 발생합니다.상위 구성 요소에는 하나의 값이 있고 하위 구성 요소에는 다른 값이 있습니다.Angular가 계속해서 변경 사항을 동기화하면 무한 루프가 발생합니다.다음 변화 감지 주기 동안 Angular가 다음을 감지한 이유입니다.allItems변경되어 오류가 발생했습니다.

해결책

업데이트 중인 응용프로그램 설계 결함인 것 같습니다.details상위 및 하위 구성 요소 모두에서.그렇지 않은 경우 다음과 같이 이벤트를 비동기적으로 실행하여 문제를 해결할 수 있습니다.

export class ChildComponent implements OnInit {
  @Output() notify: EventEmitter<any> = new EventEmitter(true);
                                                        ^^^^^^-------------

하지만 여러분은 매우 조심해야 합니다.만약 당신이 다른 후크를 사용한다면,ngAfterViewChecked그것은 모든 다이제스트 사이클에서 호출되고 있으며, 당신은 순환 의존성이 될 입니다!

저의 경우, 저는 제 데이터의 상태를 변경하고 있었습니다. 이 답변은 AngularInDepth.com 의 다이제스트 사이클 설명을 읽어야 합니다. HTML 레벨에서 제가 해야 할 일은 데이터를 다루는 방식을 다음과 같이 변경하는 것이었습니다.

<div>{{event.subjects.pop()}}</div>

안으로

<div>{{event.subjects[0]}}</div>

요약: 배열의 마지막 요소를 반환하고 제거하여 데이터의 상태를 변경하는 팝핑 대신, 데이터의 상태를 변경하지 않고 데이터를 가져오는 일반적인 방법을 사용하여 예외를 방지했습니다.

이 오류가 발생하면 다음을 사용할 수 있습니다.rxjs timer짧은 시간 동안 통화를 지연시키는 것.

이 예에서는 다음을 사용합니다.@angular/material stepperURL의 쿼리 매개 변수에서 기본 단계를 로드합니다.

import { timer } from 'rxjs'

@Component({
  template: `
    <mat-horizontal-stepper #stepper>
      <mat-step></mat-step>
      <mat-step></mat-step>
      <mat-step></mat-step>
    </mat-horizontal-stepper>
  `
})
export class MyComponent {
  @ViewChild('stepper', { static: true })
  private stepper: MatHorizontalStepper

  public ngOnInit() {
    timer(10).subscribe(() => {
      this.activatedRoute.queryParams.subscribe(params => {
        this.stepper.selectedIndex = parseInt(params.step || 0)
      })
    })
  }
}

언급URL : https://stackoverflow.com/questions/44691745/angular-4-expressionchangedafterithasbeencheckederror

반응형