ngIf - 확인 후 식이 변경되었습니다.
간단한 시나리오가 있긴 한데, 도저히 작동이 안 돼요!
내 보기에는 높이가 제한된 상자에 텍스트를 표시합니다.
서버에서 텍스트를 가져오는 중이므로 텍스트가 들어오면 보기가 업데이트됩니다.
이제 '확장' 버튼이 있습니다.ngIf
상자에 있는 텍스트가 오버플로되어 있으면 버튼이 표시됩니다.
문제는 문자를 가져오면 문자가 바뀌기 때문에 '확장' 버튼의 상태가 다음으로 바뀐다는 것입니다.true
앵글의 변화 감지가 끝난 후...
확인 후 식이 변경되었다는 오류가 나타납니다. 이전 값: 'false'입니다. 현재 값: 'true'입니다.
분명히 버튼에...라고 표시되지 않습니다.
이 플러그인 보기(콘솔에서 오류 확인...)
이걸 어떻게 만드는지 아세요?
이 오류가 발생하는 이유는 사용자가dev mode
:
dev mode
change detection은 모델이 변경되었는지 확인하기 위해 매 정기적인 변경 감지 실행 후 추가 턴을 추가합니다.
변경 탐지를 강제로 다음 체크 표시를 실행하려면 다음과 같은 작업을 수행할 수 있습니다.
export class App implements AfterViewChecked {
show = false; // add one more property
constructor(private cdRef : ChangeDetectorRef) { // add ChangeDetectorRef
//...
}
//...
ngAfterViewChecked() {
let show = this.isShowExpand();
if (show != this.show) { // check if it change, tell CD update view
this.show = show;
this.cdRef.detectChanges();
}
}
isShowExpand()
{
//...
}
}
라이브 데모: https://plnkr.co/edit/UDMNhnGt3Slg8g5yeSNO?p=preview
ngAfterContentChecked 후 변경 탐지기 실행으로 문제 해결
다음과 같은 예:
import { ChangeDetectorRef,AfterContentChecked} from '@angular/core'
export class example implements OnInit, AfterContentChecked {
ngAfterContentChecked() : void {
this.changeDetector.detectChanges();
}
}
하지만 몇몇 기사를 읽어보니 이 문제는 수정 없이 제작 모드로 해결됩니다.
아래와 같은 문제가 발생할 수 있는 이유는 다음과 같습니다.
컨트롤러 클래스의 데이터가 업데이트되면 변경 탐지가 실행되고 뷰가 업데이트되는 단방향 데이터 흐름이 적용됩니다.
그러나 뷰를 업데이트한다고 해서 그 자체가 추가 변경을 유발하는 것은 아니며, 이 변경은 뷰에 대한 추가 업데이트를 유발합니다.
https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/
시행하다AfterContentChecked
방법.
constructor(
private cdr: ChangeDetectorRef,
) {}
ngAfterContentChecked(): void {
this.cdr.detectChanges();
}
어떤 이유에서인지 @Tiep Phan의 답변은 변경 감지를 강제하는 데는 효과가 없었지만 setTimeout(변경 감지도 강제함)을 사용하는 데는 효과가 있었습니다.
저는 그것을 불쾌하게 하는 라인에만 추가하면 되었고, ngAfterViewInit을 추가하는 대신 ngOnInit에 이미 있는 코드로도 잘 작동했습니다.
예:
ngOnInit() {
setTimeout(() => this.loadingService.loading = true);
asyncFunctionCall().then(res => {
this.loadingService.loading = false;
})
}
자세한 내용은 여기: https://github.com/angular/angular/issues/6005
이 문제를 해결하기 위해 *ngIf 상태를 변경하는 변수를 ngAfterView에서 이동할 수 있습니다.ngOnInit 또는 생성자를 초기화합니다.AfterView 동안 html의 상태를 변경할 수 없기 때문입니다.Init 메서드가 호출 중입니다.
@tiep-phan이 알려준 것처럼, 다른 방법은 ChangeDetectRef를 생성자에게 전달하여 AfterView에서 *ngIf의 상태를 변경한 후에 이를.chRef.detectChanges()라고 부르는 것입니다.init 방법.
변경 탐지를 OnPush로 변경하여 이 ExpressionChanged After It Has CheckedError가 던지는 것을 억제할 수도 있습니다.따라서 추가 변경 탐지가 실행되지 않으므로 오류가 발생하지 않습니다.이를 위해서는 다음의 일부로 추가해야 합니다.@Component
.ts 파일의 데코레이터는 다음과 같습니다.
@Component({
selector: 'your-component',
templateUrl: 'your-component.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
유사한 문제로 어려움을 겪고 있는 사람들을 위해, 기본적으로 여러분은 하지 말아야 할 곳에서 돔을 업데이트하려고 노력하고 있습니다. 이 링크 https://blog.angular-university.io/angular-debugging/ 에서 디버그하는 방법에 대한 세부 정보를 찾을 수 있고, 문제를 발생시키는 정확한 코드 조각을 찾을 수 있으며, 문제를 해결하는 방법에 대한 몇 가지 아이디어를 찾을 수 있습니다.
이것은 Angular 버전 9+를 위한 것입니다.
를 사용할 때도 이 오류가 발생합니다.@ViewChild('templateRefVar') xyz!: TemplateRef
. 그 이유는 그 언급이 분명히undefind
보기가 준비될 때까지, 값이 템플릿 참조로 실제로 변경될 때 이 오류가 발생합니다.
템플릿 참조가 있는 것을 알고 있다면 다음과 같은 이유가 있습니다: xyz.html:
...
<ng-template #templateRefVar>
...
</ng-template>
...
다음과 같이 선언할 수 있습니다.static
다음과 같습니다.@ViewChild('templateRefVar', {static: true}) xyz!: TemplateRef
.
"이 옵션은 즉시 내장된 뷰를 생성할 수 있도록 지원하기 위해 도입되었습니다." - angular.io 가이드
다음 방법에 대한 자세한 내용은 를 참조하십시오.
사용하시는 경우BehaviorSubject
구성요소 간의 가치 공유를 위해:
component.ts:
import { Observable } from 'rxjs/Observable';
import {tap, map, delay} from 'rxjs/operators';
private _user = new BehaviorSubject<any>(null);
user$ = this._user.asObservable();
Observable.of('response').pipe(
tap(() =>this._user.next('yourValue'),
delay(0),
map(() => 'result')
);
구성 요소.html:
<login *ngIf="!(dataService.user$ | async); else mainComponent"></login>
확인 후 객체가 변경되는 Ngbmodal 팝업을 로드 중에 열어서 이 오류가 발생했습니다.setTimeout 안에 modal open function을 호출하여 이 문제를 해결하였습니다.
setTimeout(() => {
this.modalReference = this.modalService.open(this.modal, { size: "lg" });
});
각도 변경 탐지 프로세스는 동기화됩니다. 이 오류를 방지하기 위해 비동기 프로세스로 만들 수 있으며, 다음과 같은 작업을 수행하여 해당 코드를 변경 탐지 외부에서 실행하도록 만들 수 있습니다.이 토막글을 Init 또는 Constructor 메서드에 넣을 수 있습니다.
this.ngZone.runOutsideAngular(() => {
this.interval = window.setInterval(() => {
//logic which we want to handle
}, 1)});
언급URL : https://stackoverflow.com/questions/43513421/ngif-expression-has-changed-after-it-was-checked
'programing' 카테고리의 다른 글
날짜별 엔트리 선택 - >= NOW(), MySQL (0) | 2023.10.24 |
---|---|
jQuery 객체를 어떻게 비교하시겠습니까? (0) | 2023.10.24 |
void* 대신 intptr_t를 사용? (0) | 2023.10.24 |
문자 뺄셈을 이용한 cstrcmp 구현 (0) | 2023.10.24 |
jQuery로 텍스트 내용별 옵션 선택 (0) | 2023.10.24 |