AngularJS에서는의 $watch
기능을 사용하여 범위 변수의 변화를 관찰 할 감시자를 지정할 수있었습니다 $scope
. Angular에서 변수 변경 (예 : 구성 요소 변수)을 관찰하는 것과 동등한 것은 무엇입니까?
답변
Angular 2에서 변경 감지는 자동으로 수행 $scope.$watch()
되며 $scope.$digest()
RIP
불행하게도, 개발 가이드의 변경 감지 섹션은 아직 작성되지 않았습니다 ( 아키텍처 개요 페이지 하단 근처의 “기타 항목”에 자리 표시자가 있음).
변경 감지 작동 방식에 대한 이해는 다음과 같습니다.
- Zone.js “원숭이가 세상을 패치한다”-브라우저에서 모든 비동기 API를 가로 챈다 (Angular가 실행될 때). 이것이 원숭이 패치 이기 때문에
setTimeout()
우리가 구성 요소 내부에서 사용할 수있는 이유 입니다.$timeout
setTimeout()
- Angular는 “변경 감지기”트리를 구축하고 유지합니다. 구성 요소 / 지시문마다 이러한 변경 감지기 (클래스)가 있습니다. 을 주입하여이 객체에 액세스 할 수 있습니다
ChangeDetectorRef
. 이러한 변경 감지기는 Angular가 구성 요소를 만들 때 만들어집니다. 더티 검사를 위해 모든 바인딩 상태를 추적합니다. 이것은$watches()
Angular 1이{{}}
템플릿 바인딩 을 위해 설정 한 것과 자동으로 비슷합니다 .
Angular 1과 달리 변경 감지 그래프는 방향이 지정된 트리이며주기를 가질 수 없습니다 (아래에서 볼 수 있듯이 Angular 2의 성능이 훨씬 향상됩니다). - 이벤트가 발생하면 (앵귤러 영역 내에서) 우리가 작성한 코드 (이벤트 핸들러 콜백)가 실행됩니다. 공유 응용 프로그램 모델 / 상태 및 / 또는 구성 요소의보기 상태 등 원하는 데이터를 업데이트 할 수 있습니다.
- 그 후 Zone.js가 추가 된 후크 때문에 Angular의 변경 감지 알고리즘을 실행합니다. 기본적으로 (즉,
onPush
구성 요소 중 하나 에서 변경 감지 전략을 사용하지 않는 경우 ) 트리의 모든 구성 요소는 맨 처음부터 깊이 우선 순서대로 한 번 (TTL = 1) 검사됩니다. (개발 모드 인 경우 변경 감지가 두 번 실행됩니다 (TTL = 2). 이에 대한 자세한 내용은 ApplicationRef.tick () 를 참조하십시오 .) 변경 감지 오브젝트를 사용하여 모든 바인딩에 대해 더티 검사를 수행합니다.- 수명주기 후크는 변경 감지의 일부로 호출됩니다.
보고자하는 구성 요소 데이터가 기본 입력 특성 (문자열, 부울, 숫자)ngOnChanges()
인 경우 변경 사항을 통지하도록 구현할 수 있습니다.
입력 속성이 참조 유형 (객체, 배열 등)이지만 참조가 변경되지 않은 경우 (예 : 기존 배열에 항목을 추가 한 경우) 구현해야합니다ngDoCheck()
(자세한 내용은 이 SO 답변 참조). 이에).
단일 트리 워크 구현 (단방향 데이터 흐름) 때문에 구성 요소의 속성 및 / 또는 하위 구성 요소의 속성 만 변경해야합니다. 여기에 위배 되는 플런저 가 있습니다. 상태 보존 형 파이프도 할 수 당신을 여행 여기.
- 수명주기 후크는 변경 감지의 일부로 호출됩니다.
- 발견 된 바인딩 변경 사항에 대해 구성 요소가 업데이트 된 후 DOM이 업데이트됩니다. 변경 감지가 완료되었습니다.
- 브라우저는 DOM 변경 사항을 확인하고 화면을 업데이트합니다.
자세한 내용은 다음을 참조하십시오.
- Angular의 $ digest는 새로운 버전의 Angular에서 다시 태어났습니다 -AngularJS의 아이디어 가 Angular에 어떻게 매핑되는지 설명합니다
- Angular에서 변경 감지에 대해 알아야 할 모든 것 -변경 감지가 어떻게 작동하는지 자세히 설명합니다.
- 변경 감지 설명 -Thoughtram 블로그 2016 년 2 월 22 일-아마도 최상의 참조
- Savkin의 변경 감지 재창조 된 비디오-이 비디오를 꼭보십시오
- Angular 2 변경 감지는 실제로 어떻게 작동합니까? -jhade의 블로그 2016 년 2 월 24 일
- Zone.js에 대한 Brian의 비디오 와 Miško의 비디오. Brian은 Zone.js에 관한 것입니다. Miško는 Angular 2가 Zone.js를 사용하여 변경 감지를 구현하는 방법에 관한 것입니다. 그는 또한 일반적으로 변경 감지에 대해 이야기하고 약간에 대해 이야기
onPush
합니다. - Victor Savkins 블로그 게시물 : Angular 2의 변경 감지 , Angular 2 애플리케이션의 2 단계 , Angular, Immutability 및 Encapsulation . 그는 빨리 많은 땅을 덮지 만 때때로 간결 할 수 있으며, 당신은 머리를 긁적 거리며 잃어버린 조각에 대해 궁금해합니다.
- 초고속 변경 감지 (Google 문서)-매우 기술적이고 간결하지만 트리의 일부로 생성 된 ChangeDetection 클래스를 설명 / 스케치합니다.
답변
이 동작은 이제 구성 요소 수명주기의 일부입니다.
구성 요소는 OnChanges 인터페이스 에서 ngOnChanges 메서드를 구현하여 입력 변경에 액세스 할 수 있습니다.
예:
import {Component, Input, OnChanges} from 'angular2/core';
@Component({
selector: 'hero-comp',
templateUrl: 'app/components/hero-comp/hero-comp.html',
styleUrls: ['app/components/hero-comp/hero-comp.css'],
providers: [],
directives: [],
pipes: [],
inputs:['hero', 'real']
})
export class HeroComp implements OnChanges{
@Input() hero:Hero;
@Input() real:string;
constructor() {
}
ngOnChanges(changes) {
console.log(changes);
}
}
답변
자동 양방향 바인딩 외에도 값이 변경 될 때 함수를 호출하려는 경우 양방향 바인딩 바로 가기 구문을보다 자세한 버전으로 분리 할 수 있습니다.
<input [(ngModel)]="yourVar"></input>
속기
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(예 : http://victorsavkin.com/post/119943127151/angular-2-template-syntax 참조 )
다음과 같이 할 수 있습니다.
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
답변
각도 2에서 시계를 사용 getter function
하거나 get accessor
시계 역할을 할 수 있습니다 .
import {Component} from 'angular2/core';
@Component({
// Declare the tag name in index.html to where the component attaches
selector: 'hello-world',
// Location of the template for this component
template: `
<button (click)="OnPushArray1()">Push 1</button>
<div>
I'm array 1 {{ array1 | json }}
</div>
<button (click)="OnPushArray2()">Push 2</button>
<div>
I'm array 2 {{ array2 | json }}
</div>
I'm concatenated {{ concatenatedArray | json }}
<div>
I'm length of two arrays {{ arrayLength | json }}
</div>`
})
export class HelloWorld {
array1: any[] = [];
array2: any[] = [];
get concatenatedArray(): any[] {
return this.array1.concat(this.array2);
}
get arrayLength(): number {
return this.concatenatedArray.length;
}
OnPushArray1() {
this.array1.push(this.array1.length);
}
OnPushArray2() {
this.array2.push(this.array2.length);
}
}
답변
다음은 모델에 getter 및 setter 함수를 사용하는 다른 방법입니다.
@Component({
selector: 'input-language',
template: `
…
<input
type="text"
placeholder="Language"
[(ngModel)]="query"
/>
`,
})
export class InputLanguageComponent {
set query(value) {
this._query = value;
console.log('query set to :', value)
}
get query() {
return this._query;
}
}
답변
양방향 바인딩으로 만들려면을 사용할 수 [(yourVar)]
있지만 yourVarChange
변수를 변경할 때마다 이벤트 를 구현 하고 호출해야합니다.
영웅 변화를 추적하기 위해 이와 같은 것
@Output() heroChange = new EventEmitter();
영웅이 바뀌면 전화 해 this.heroChange.emit(this.hero);
[(hero)]
당신을위한 나머지를 할 것 바인딩
여기 예를보십시오 :
답변
응용 프로그램이 때를 시도 여전히 요구 $parse
, $eval
, $watch
각도의 행동처럼