AngularJS에서는의 $watch
기능을 사용하여 범위 변수의 변화를 관찰 할 감시자를 지정할 수있었습니다 $scope
. Angular에서 변수 변경 (예 : 구성 요소 변수)을 관찰하는 것과 동등한 것은 무엇입니까?
AngularJS에서는의 $watch
기능을 사용하여 범위 변수의 변화를 관찰 할 감시자를 지정할 수있었습니다 $scope
. Angular에서 변수 변경 (예 : 구성 요소 변수)을 관찰하는 것과 동등한 것은 무엇입니까?
답변:
Angular 2에서 변경 감지는 자동으로 수행 $scope.$watch()
되며 $scope.$digest()
RIP
불행하게도, 개발 가이드의 변경 감지 섹션은 아직 작성되지 않았습니다 ( 아키텍처 개요 페이지 하단 근처의 "기타 항목"에 자리 표시자가 있음).
변경 감지 작동 방식에 대한 이해는 다음과 같습니다.
setTimeout()
우리가 구성 요소 내부에서 사용할 수있는 이유 입니다.$timeout
setTimeout()
ChangeDetectorRef
. 이러한 변경 감지기는 Angular가 구성 요소를 만들 때 만들어집니다. 더티 검사를 위해 모든 바인딩 상태를 추적합니다. 이것은 $watches()
Angular 1이 {{}}
템플릿 바인딩 을 위해 설정 한 것과 자동으로 비슷합니다 . onPush
구성 요소 중 하나 에서 변경 감지 전략을 사용하지 않는 경우 ) 트리의 모든 구성 요소는 맨 처음부터 깊이 우선 순서대로 한 번 (TTL = 1) 검사됩니다. (개발 모드 인 경우 변경 감지가 두 번 실행됩니다 (TTL = 2). 이에 대한 자세한 내용은 ApplicationRef.tick () 를 참조하십시오 .) 변경 감지 오브젝트를 사용하여 모든 바인딩에 대해 더티 검사를 수행합니다.
ngOnChanges()
인 경우 변경 사항을 통지하도록 구현할 수 있습니다. ngDoCheck()
(자세한 내용은 이 SO 답변 참조). 이에). 자세한 내용은 다음을 참조하십시오.
onPush
합니다.host
는 DirectiveMetadata API 문서 의 "호스트 리스너"문서를 참조하십시오 . Angular 영역 내에서 글로벌 이벤트를 듣는 방법을 설명합니다 (따라서 변경 감지가 원하는대로 트리거됩니다). 이 답변 에는 작동하는 플런 커가 있습니다.
이 동작은 이제 구성 요소 수명주기의 일부입니다.
구성 요소는 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;
}
}
(change)
그들 각각에 핸들러 를 추가하고 싶지 않다 . get|sets
내 모델의 모든 속성에 s 를 추가하고 싶지 않습니다 . 그것은을 추가하는 데 도움이되지 않습니다 get|set
에 대한 this.object
; ngOnChanges()
단지 변경 감지 @Input
들 . 이런 만나요! 그들은 우리에게 무엇을 했습니까 ??? 우리에게 어떤 종류의 깊은 시계를 돌려주십시오!
양방향 바인딩으로 만들려면을 사용할 수 [(yourVar)]
있지만 yourVarChange
변수를 변경할 때마다 이벤트 를 구현 하고 호출해야합니다.
영웅 변화를 추적하기 위해 이와 같은 것
@Output() heroChange = new EventEmitter();
영웅이 바뀌면 전화 해 this.heroChange.emit(this.hero);
[(hero)]
당신을위한 나머지를 할 것 바인딩
여기 예를보십시오 :
응용 프로그램이 때를 시도 여전히 요구 $parse
, $eval
, $watch
각도의 행동처럼
이것은 질문에 직접 대답하지는 않지만 angularJs에서 $ watch를 사용할 무언가를 해결하기 위해이 스택 오버플로 질문에 착수했습니다. 나는 현재 답변에 설명 된 것과 다른 접근법을 사용하여 누군가가 유용하다고 생각하는 경우 공유하고 싶습니다.
나는 비슷한 달성하기 위해 사용하는 기술은 $watch
사용하는 것입니다 BehaviorSubject
( 여기에 주제에 대한 더 많은 각도 서비스), 내 구성 요소가 변경 (시계)를 얻기 위해 여기에 가입 할 수 있습니다. 이것은 $watch
앵귤러 J 와 비슷 하지만 더 많은 설정과 이해가 필요합니다.
내 구성 요소에서 :
export class HelloComponent {
name: string;
// inject our service, which holds the object we want to watch.
constructor(private helloService: HelloService){
// Here I am "watching" for changes by subscribing
this.helloService.getGreeting().subscribe( greeting => {
this.name = greeting.value;
});
}
}
내 서비스에서
export class HelloService {
private helloSubject = new BehaviorSubject<{value: string}>({value: 'hello'});
constructor(){}
// similar to using $watch, in order to get updates of our object
getGreeting(): Observable<{value:string}> {
return this.helloSubject;
}
// Each time this method is called, each subscriber will receive the updated greeting.
setGreeting(greeting: string) {
this.helloSubject.next({value: greeting});
}
}
다음은 Stackblitz 의 데모입니다 .