-
09 파이프(Pipe) 04앵귤러/03 템플릿&데이터 바인딩 2017. 9. 2. 22:02
Pure와 impure 파이프
파이프에는 두 가지 범주가 있습니다. Pure와 impure입니다. 파이프는 기본적으로 pure입니다. 지금까지 본 모든 파이프는 pure입니다. pure 플래그를 false로 설정하여 파이프를 impure로 만듭니다. 다음과 같이 FlyingHeroesPipe를 impure로 만들 수 있습니다.
src/app/flying-heroes.pipe.ts
@Pipe({
name: 'flyingHeroesImpure',
pure: false
})
pure와 impure의 차이점을 이해해야 합니다. pure 파이프로 시작합니다.
pure 파이프
Angular는 입력 값에 대한 pure 변경을 감지 한 경우에만 pure 파이프를 실행합니다. pure 변경은 원시 입력 값 (String, Number, Boolean, Symbol) 또는 변경된 객체 참조 (Date, Array, Function, Object) 로의 변경입니다.
Angular는 (복합)객체 내의 변경 사항을 무시합니다. 입력 월을 변경하거나 입력 배열에 추가하거나 입력 개체 속성을 업데이트하면 pure 파이프가 호출되지 않습니다.
이것은 제한적으로 보일 수 있지만 빠릅니다. 객체 참조 검사는 차이점에 대한 심층 검사보다 빠르며 빠르기 때문에 Angular는 파이프 실행 및 뷰 업데이트를 건너 뛸 수 있는지 신속하게 판단 할 수 있습니다.
이러한 이유 때문에 변경 감지 전략을 적용 할 때 pure 파이프를 사용하는 것이 좋습니다. 할 수 없으면 impure 파이프를 사용할 수 있습니다.
파이프를 전혀 사용하지 않을 수도 있습니다. 이 컴포넌트의 프로퍼티로 파이프의 용도를 추구하는 것이 더 나을 수도 있습니다. 이 내용은 이 페이지의 뒷부분에서 설명합니다.
impure 파이프
Angular는 모든 컴포넌트 변경 감지 사이클 동안 impure 파이프를 실행합니다. impure 파이프는 종종 모든 키 스트로크 또는 마우스 이동처럼 자주 호출됩니다.
이러한 염려를 염두에두고, impure 파이프를 세 심하게 구현하십시오. 비싸고 오래 실행되는 파이프는 사용자 환경을 파괴 할 수 있습니다.
impure FlyingHeroesPipe
FlyingHeroesPipe를 FlyingHeroesImpurePipe로 변경합니다. 전체 구현은 다음과 같습니다.
FlyingHeroesImpurePipe
@Pipe({
name: 'flyingHeroesImpure',
pure: false
})
export class FlyingHeroesImpurePipe extends FlyingHeroesPipe {}
FlyingHeroesPipe
import { Pipe, PipeTransform } from '@angular/core';
import { Flyer } from './heroes';
@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
transform(allHeroes: Flyer[]) {
return allHeroes.filter(hero => hero.canFly);
}
}
FlyingHeroesPipe에서 상속받은 내용은 내부적으로 변경된 사항이 없음을 증명합니다. 유일한 차이점은 파이프 메타 데이터의 pure 플래그입니다.
이것은 transform 함수가 사소하고 빠르기 때문에 impure 파이프에 대한 좋은 후보입니다.
src/app/flying-heroes.pipe.ts (filter)
return allHeroes.filter(hero => hero.canFly);
FlyingHeroesComponent에서 FlyingHeroesImpureComponent를 파생시킬 수 있습니다.
src/app/flying-heroes-impure.component.html (excerpt)
<div *ngFor="let hero of (heroes | flyingHeroesImpure)">
{{hero.name}}
</div>
유일한 실질적인 변화는 템플릿의 파이프입니다. 라이브 예제 / 예제 다운로드에서 heroes 배열의 내용을 변경할 때, 영웅을 추가 할 때 비행 영웅이 수정된 내역을 표시한다는 것을 확인할 수 있습니다.
impure AsyncPipe
Angular AsyncPipe는 impure 파이프의 흥미로운 예입니다. AsyncPipe는 Promise 또는 Observable을 입력으로 받아들이고 입력을 자동으로 구독하며, 결국 방출 된 값을 리턴합니다.
AsyncPipe는 또한 상태기반입니다. 파이프는 입력Observable에 대한 구독을 유지하고 Observable에서 값을 전달합니다.
다음 예제는 Observable 메시지 문자열 (message$)을 async 파이프가 있는 뷰에 바인딩합니다.
src/app/hero-async-message.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
@Component({
selector: 'hero-message',
template: `
<h2>Async Hero Message and AsyncPipe</h2>
<p>Message: {{ message$ | async }}</p>
<button (click)="resend()">Resend</button>`,
})
export class HeroAsyncMessageComponent {
message$: Observable<string>;
private messages = [
'You are my hero!',
'You are the best hero!',
'Will you be my hero?'
];
constructor() { this.resend(); }
resend() {
this.message$ = Observable.interval(500)
.map(i => this.messages[i])
.take(this.messages.length);
}
}
비동기 파이프는 컴포넌트 코드에 상용구를 저장합니다. 컴포넌트는 비동기 데이터 소스에 가입 할 필요가 없으며 확인 된 값을 추출하여 바인딩 용으로 노출하고 파괴 될 때 가입을 취소해야합니다 (강력한 메모리 누수 원인).
impure 캐싱 파이프
HTTP 요청을하는 파이프 인 impure 파이프를 하나 더 작성하십시오.
impure 파이프는 몇 밀리 초마다 호출된다는 점을 기억하십시오. 조심하지 않으면이 파이프가 요청으로 서버를 망가뜨립니다.
다음 코드에서 파이프는 요청 URL이 변경되면 서버를 호출하고 서버 응답을 캐시합니다. 이 코드는 Angular http 클라이언트를 사용하여 데이터를 가져옵니다.
src/app/fetch-json.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Pipe({
name: 'fetch',
pure: false
})
export class FetchJsonPipe implements PipeTransform {
private cachedData: any = null;
private cachedUrl = '';
constructor(private http: Http) { }
transform(url: string): any {
if (url !== this.cachedUrl) {
this.cachedData = null;
this.cachedUrl = url;
this.http.get(url)
.map( result => result.json() )
.subscribe( result => this.cachedData = result );
}
return this.cachedData;
}
}
템플릿이이 파이프에 대한 두 개의 바인딩을 정의하는 하네스 컴포넌트에서 이를 보여줍니다. 둘 다 heroes.json 파일에서 영웅을 요청합니다.
src/app/hero-list.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'hero-list',
template: `
<h2>Heroes from JSON File</h2>
<div *ngFor="let hero of ('heroes.json' | fetch) ">
{{hero.name}}
</div>
<p>Heroes as JSON:
{{'heroes.json' | fetch | json}}
</p>`
})
export class HeroListComponent { }
컴포넌트는 다음과 같이 표출합니다.
파이프에 대한 데이터 요청의 중단 점은 다음을 보여줍니다.
l 모든 바인딩은 자체 파이프 인스턴스를 가져옵니다.
l 모든 파이프 인스턴스는 자체 URL과 데이터를 캐시합니다.
l 모든 파이프 인스턴스는 서버를 한 번만 호출합니다.
JsonPipe
이전 코드 샘플에서 두 번째 fetch 파이프 바인딩은 더 많은 파이프 연결을 보여줍니다. 내장 JsonPipe에 연결하여 JSON 형식의 동일한 영웅 데이터를 표시합니다.
JSON 파이프로 디버깅하기
JsonPipe는 실패한 알수없는 데이터 바인딩오류를 진단하거나 향후 바인딩을 위해 객체를 검사하는 쉬운 방법을 제공합니다.
'앵귤러 > 03 템플릿&데이터 바인딩' 카테고리의 다른 글
10 애니메이션(Animation) 01 (0) 2017.09.02 09 파이프(Pipe) 05 (0) 2017.09.02 09 파이프(Pipe) 03 (0) 2017.09.02 09 파이프(Pipe) 02 (0) 2017.09.02 09 파이프(Pipe) 01 (0) 2017.09.02