IT

Angular 2 변경 감지는 어떻게 작동합니까?

itgroup 2023. 2. 22. 21:42
반응형

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

반응형