[Angular] 모델, 값이 바뀌었는데 화면 template 이 업데이트 되지 않을 때 조치 팁

안녕하세요. 명동섞어찌개입니다.

Angular 로 화면을 만들다 보면 종종 서버에서 값을 읽어와서 비동기로 화면이 업데이트 되는 상황에서, 화면에 바뀐 값이 반영되지 않는 경우가 생깁니다.

분명 ts (typescript) 의 값은 바뀌었고, 서버에도 문제가 없는데 html template 화면만 값이 제대로 표시되지 않는 경우가 있습니다.

이럴 때 사용할 수 있는 간단한 방법을 공유하려고 합니다.


1. ngIf = "flag == true" 를 씁니다.

data.html

1
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();
}







댓글

주간 인기글

SPA(Sigle Page Applications) 란 무엇인가?

[앱 디자인] 디자인 가이드 만들기 - 안드로이드

[ubuntu] 신규 계정에 sudo 권한 추가하기

Nodejs 날짜 관련 유용한 moment.js

[Android] Parcelable 에 대한 쉬운 이해