[Angular] 모델, 값이 바뀌었는데 화면 template 이 업데이트 되지 않을 때 조치 팁
안녕하세요. 명동섞어찌개입니다.
Angular 로 화면을 만들다 보면 종종 서버에서 값을 읽어와서 비동기로 화면이 업데이트 되는 상황에서, 화면에 바뀐 값이 반영되지 않는 경우가 생깁니다.
분명 ts (typescript) 의 값은 바뀌었고, 서버에도 문제가 없는데 html template 화면만 값이 제대로 표시되지 않는 경우가 있습니다.
이럴 때 사용할 수 있는 간단한 방법을 공유하려고 합니다.
data.ts
비동기로 서버에서 값을 읽어올 때, 값이 들어온 시점에 (data.length > 1) 정확히 데이터를 들고 화면을 그려주기 위해 template 쪽에 ngIf 문을 이용해서 그려줍니다.
저런식으로 화면 일부가 데이터가 계속 바뀜에 따라 지속적으로 업데이트 되어야 하는데, 값은 잘 들어오지만 template 은 새로 그려지지 않을때 flag 를 하나 세팅해서 ngIf 로 제어하면 화면이 잘 바뀝니다.
예를 들어
[A 컴포넌트] ---(click)---> [B 컴포넌트]
A 컴포넌트에서 메인 메뉴를 클릭할 때 B 컴포넌트에서 각 서브메뉴 값들을 서버에서 새로 불러오는 상황에서
ts 는 값이 문제 없이 찍히는데 화면 템플릿은 업데이트 되지 않을 때
<componentB *ngIf="flag"></componentB>
로 플래그를 걸어주고
click 시점에 flag = false; 로 세팅해주고, 서비스에서 데이터를 읽어오면 flag = true 로 바꿔주면 문제없이 화면이 업데이트 됩니다.
실무에서는 이거라도 써야 할 수 밖에 없는 상황이 가끔 생기죠.
this.zone.run 안쪽에 화면 템플릿에서 업데이트 되어야 하는 변수 변화를 처리하시면 됩니다.
Angular 로 화면을 만들다 보면 종종 서버에서 값을 읽어와서 비동기로 화면이 업데이트 되는 상황에서, 화면에 바뀐 값이 반영되지 않는 경우가 생깁니다.
분명 ts (typescript) 의 값은 바뀌었고, 서버에도 문제가 없는데 html template 화면만 값이 제대로 표시되지 않는 경우가 있습니다.
이럴 때 사용할 수 있는 간단한 방법을 공유하려고 합니다.
1. ngIf = "flag == true" 를 씁니다.
data.html1 2 3 4 5 | <div *ngIf="data.length > 1"> <span *ngFor="let item of data; let idx=index"> <span>{{item}}</span> </span> </div> |
data.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | data = null; . . . getData() { this.dataService.getDatas().subscribe( data => { this.data = data.result; }, ( {error} ) => { } ) } |
비동기로 서버에서 값을 읽어올 때, 값이 들어온 시점에 (data.length > 1) 정확히 데이터를 들고 화면을 그려주기 위해 template 쪽에 ngIf 문을 이용해서 그려줍니다.
저런식으로 화면 일부가 데이터가 계속 바뀜에 따라 지속적으로 업데이트 되어야 하는데, 값은 잘 들어오지만 template 은 새로 그려지지 않을때 flag 를 하나 세팅해서 ngIf 로 제어하면 화면이 잘 바뀝니다.
예를 들어
[A 컴포넌트] ---(click)---> [B 컴포넌트]
A 컴포넌트에서 메인 메뉴를 클릭할 때 B 컴포넌트에서 각 서브메뉴 값들을 서버에서 새로 불러오는 상황에서
ts 는 값이 문제 없이 찍히는데 화면 템플릿은 업데이트 되지 않을 때
<componentB *ngIf="flag"></componentB>
로 플래그를 걸어주고
click 시점에 flag = false; 로 세팅해주고, 서비스에서 데이터를 읽어오면 flag = true 로 바꿔주면 문제없이 화면이 업데이트 됩니다.
2. ngZone
화면 성능이 느려질 수 있어서 권장하는 방법은 아닙니다만,실무에서는 이거라도 써야 할 수 밖에 없는 상황이 가끔 생기죠.
this.zone.run 안쪽에 화면 템플릿에서 업데이트 되어야 하는 변수 변화를 처리하시면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | import { NgZone } from '@angular/core'; . . . constructor( private zone:NgZone ) { this.zone.run(() => { console.log('데이터 바꾸기'); }); } |
3. ChangeDetectorRef
앵귤러 6 이후.. ? 에 나온 아이입니다. html template 과 ts 가 시점이 따로 놀 때 detectChanges 를 쓰면 됩니다.1 2 3 4 5 6 7 8 9 10 | constructor( private cd: ChangeDetectorRef ) { } . . . ngAfterViewChecked() { this.cd.detectChanges(); } |
좋은정보 감사합니다
답글삭제