[angularjs] Angular는 AngularJS $ watch와 동일합니까?

AngularJS에서는의 $watch기능을 사용하여 범위 변수의 변화를 관찰 할 감시자를 지정할 수있었습니다 $scope. Angular에서 변수 변경 (예 : 구성 요소 변수)을 관찰하는 것과 동등한 것은 무엇입니까?



답변

Angular 2에서 변경 감지는 자동으로 수행 $scope.$watch()되며 $scope.$digest()RIP

불행하게도, 개발 가이드의 변경 감지 섹션은 아직 작성되지 않았습니다 ( 아키텍처 개요 페이지 하단 근처의 “기타 항목”에 자리 표시자가 있음).

변경 감지 작동 방식에 대한 이해는 다음과 같습니다.

  • Zone.js “원숭이가 세상을 패치한다”-브라우저에서 모든 비동기 API를 가로 챈다 (Angular가 실행될 때). 이것이 원숭이 패치 이기 때문에 setTimeout()우리가 구성 요소 내부에서 사용할 수있는 이유 입니다.$timeoutsetTimeout()
  • 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 변경 사항을 확인하고 화면을 업데이트합니다.

자세한 내용은 다음을 참조하십시오.


답변

이 동작은 이제 구성 요소 수명주기의 일부입니다.

구성 요소는 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)]당신을위한 나머지를 할 것 바인딩

여기 예를보십시오 :

http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview


답변

응용 프로그램이 때를 시도 여전히 요구 $parse, $eval, $watch각도의 행동처럼

https://github.com/vinayk406/angular-expression-parser