Angular 2 변경 감지는 어떻게 작동합니까?
Angular 1에서는 $scope 계층을 더티 체크함으로써 변경 검출이 이루어졌습니다.템플릿, 컨트롤러 또는 컴포넌트에 암묵적으로 또는 명시적으로 워처를 작성합니다.
Angular 2에서는 $scope는 없지만 setInterval, setTimeout 등을 덮어씁니다.Angular가 이를 사용하여 $digest를 트리거하는 방법은 알 수 있지만, Object.observe가 브라우저로 만든 적이 없는 점을 감안할 때 Angular는 무엇이 변경되었는지 어떻게 판단합니까?
예
여기 간단한 예가 있습니다.서비스에서 정의된 개체가 setInterval에서 업데이트됩니다.DOM 는, 각 인터벌 마다 재컴파일 됩니다.
Angular는 App Component가 서비스를 감시하고 있으며 서비스 속성 값이 변경되었음을 어떻게 알 수 있습니까?
var InjectedService = function() {
var val = {a:1}
setInterval(() => val.a++, 1000);
return val;
}
var AppComponent = ng.core
.Component({
selector: "app",
template:
`
{{service.a}}
`
})
.Class({
constructor: function(service) {
this.service = service;
}
})
AppComponent.parameters = [ new ng.core.Inject( InjectedService ) ];
document.addEventListener('DOMContentLoaded', function() {
ng.platform.browser.bootstrap(AppComponent, [InjectedService])
});
Angular는 컴포넌트별로 변경 디텍터 객체(ChangeDetectorRef 참조)를 만듭니다.이 오브젝트는 다음과 같이 각 템플릿바인딩의 마지막 값을 추적합니다.{{service.a}}
디폴트로는 모든 비동기 브라우저 이벤트(서버로부터의 응답, 클릭 이벤트, 타임아웃 이벤트 등) 후에 Angular Change Detection이 실행되고 이러한 변경 디텍터 개체를 사용하여 모든 바인딩이 더티 체크됩니다.
변경이 검출되면 변경이 전파됩니다.예.,
- 입력 속성 값이 변경된 경우 새 값이 구성 요소의 입력 속성으로 전파됩니다.
- 만약 a가
{{}}
바인딩 값이 변경되어 새 값이 DOM 속성에 전파됩니다.textContent
. - 의 가치가
x
스타일, 속성 또는 클래스 바인딩의 변경:[style.x]
또는[attr.x]
또는[class.x]
– 스타일, HTML 속성 또는 클래스를 업데이트하기 위해 새 값이 DOM으로 전파됩니다.
Angular는 Zone.js를 사용하여 자체 존(NgZone)을 만듭니다.이 존에서는 모든 비동기 이벤트(브라우저 DOM 이벤트, 타임아웃, AJAX/XHR)가 원숭이 패치로 처리됩니다.이렇게 하면 각 비동기 이벤트 후에 변경 검출을 자동으로 실행할 수 있습니다.즉, 각 비동기 이벤트 핸들러(함수)가 완료되면 각도 변경 검출이 실행됩니다.
이 답변에는 더 자세한 내용과 참조 링크가 있습니다.Angular2는 Angular2와 같습니까?JS $watch?
Zone.js
변화는 무언가에 대한 반응으로 발생하므로, 이 점에서 그것들은 비동기적입니다.이러한 동작은 비동기 액션에 의해 발생하며 브라우저 월드에서는 이벤트라고 합니다.이러한 이벤트를 가로채기 위해 angular는 zone.js를 사용합니다.zone.js는 JavaScript 콜스택에 패치를 적용하고(내가 틀렸다면 누군가가 수정해준다), 다른 액션을 취하기 위해 사용할 수 있는 후크를 표시합니다.
function angular() {...}
zone.run(angular);
을 하면angular
함수는 전체 Angular이며, 이것이 존에서 실행되는 방법입니다.이를 통해 이벤트를 대행 수신할 수 있으며 이벤트가 트리거되면 변경이 발생했다고 가정하고 이벤트를 수신/관찰할 수 있습니다.
응용 프로그램 참조
실제로는 존을 만듭니다.
/**
* Create an Angular zone.
*/
export function createNgZone(): NgZone {
return new NgZone({enableLongStackTrace: assertionsEnabled()});
}
클래스 ★★★★★NgZone
이벤트 송신기가 거의 없는 상태로 작성됩니다.
this._onTurnStartEvents = new EventEmitter(false);
this._onTurnDoneEvents = new EventEmitter(false);
this._onEventDoneEvents = new EventEmitter(false);
this._onErrorEvents = new EventEmitter(false);
Getter를 통해 외부에 노출됩니다.
get onTurnStart(): /* Subject */ any { return this._onTurnStartEvents; }
get onTurnDone() { return this._onTurnDoneEvents; }
get onEventDone() { return this._onEventDoneEvents; }
get onError() { return this._onErrorEvents; }
ApplicationRef
생성되어 존의 이벤트에 서브스크라이브 합니다.onTurnDone()
:
this.zone.onTurnDone
.subscribe(() => this.zone.run(() => this.tick());
변화들
이벤트가 트리거되면 모든 컴포넌트를 루프하는 기능이 실행됩니다.
this._changeDetectorRefs.forEach((detector) => detector.detectChanges());
컴포넌트 정보를 바탕으로 변경을 검출합니다.ChangeDetectionStrategy
. 이러한 변경은 개체의 배열로 수집됩니다.
addChange(changes: {[key: string]: any}, oldValue: any, newValue: any): {[key: string]: any} {
if (isBlank(changes)) {
changes = {};
}
changes[this._currentBinding().name] = ChangeDetectionUtil.simpleChange(oldValue, newValue);
return changes;
}
witch는 인터페이스를 통해 사용할 수 있습니다.
export interface OnChanges {
ngOnChanges(changes: {[key: string]: SimpleChange});
}
언급URL : https://stackoverflow.com/questions/35469024/how-does-angular-2-change-detection-work
'IT' 카테고리의 다른 글
워드프레스를 사용해서 입력을 삭제하는 가장 좋은 방법을 알려주시겠어요? (0) | 2023.02.22 |
---|---|
jQuery 없이 $http로 urlencoded 폼 데이터를 POST하려면 어떻게 해야 합니까? (0) | 2023.02.22 |
react-testing-library - 화면과 렌더 쿼리 (0) | 2023.02.22 |
Redux와 릴레이의 차이점 (0) | 2023.02.22 |
Django queryset.values()를 json으로 시리얼화하려면 어떻게 해야 합니까? (0) | 2023.02.22 |