나는 모두 알고 Watchers
그리고 Observers
뭔가 즉시 계산된다 $scope
AngularJS와 변화. 그러나 둘 사이의 차이점이 정확히 무엇인지 이해할 수 없었습니다.
내 초기 이해는 함수가 실행될 때 실행되는 Observers
HTML 측의 조건 인 각도 표현식에 대해 계산 된다는 것입니다 . 제대로 생각하고 있습니까?Watchers
$scope.$watch()
나는 모두 알고 Watchers
그리고 Observers
뭔가 즉시 계산된다 $scope
AngularJS와 변화. 그러나 둘 사이의 차이점이 정확히 무엇인지 이해할 수 없었습니다.
내 초기 이해는 함수가 실행될 때 실행되는 Observers
HTML 측의 조건 인 각도 표현식에 대해 계산 된다는 것입니다 . 제대로 생각하고 있습니까?Watchers
$scope.$watch()
답변:
$ observe () 는 Attributes 객체의 메소드이므로 DOM 속성의 값 변경을 관찰 / 감시하는 데만 사용할 수 있습니다. 내부 지시문 만 사용 / 호출됩니다. 보간 (예 : {{}})이 포함 된 DOM 속성을 관찰 / 감시해야 할 경우 $ observe를 사용하십시오.
예를 들어attr1="Name: {{name}}"
지시문에서 :attrs.$observe('attr1', ...)
.
(당신이하려고하면scope.$watch(attrs.attr1, ...)
때문에 {{}}의의는하지 않습니다 작업 - 당신이 얻을 수 있습니다undefined
.) 다른 모든 것들에 대한 사용 $ 시계.
$ watch () 가 더 복잡합니다. "표현식"을 관찰 / 관찰 할 수 있으며, 표현식은 함수 또는 문자열 일 수 있습니다. 표현식이 문자열 인 경우함수에 $ parse 'd (즉, Angular expression으로 평가됨)입니다. (이 함수는 모든 다이제스트주기라고합니다.) 문자열 표현식은 {{}}을 (를) 포함 할 수 없습니다. $ watch는 Scope 객체의 메소드이므로 스코프 객체에 액세스 할 수있는 모든 곳에서 사용 / 호출 할 수 있습니다.
문자열은 각도 식으로 평가되므로 모델 / 범위 속성을 관찰 / 감시 할 때 $ watch가 종종 사용됩니다. 예를 들어 attr1="myModel.some_prop"
컨트롤러 또는 링크 기능에서 : scope.$watch('myModel.some_prop', ...)
또는 scope.$watch(attrs.attr1, ...)
(또는 scope.$watch(attrs['attr1'], ...)
).
(당신이 시도 attrs.$observe('attr1')
하면 문자열 myModel.some_prop
이 될 것입니다. 아마도 원하는 것이 아닙니다.)
@PrimosK의 답변에 대한 의견에서 논의했듯이 모든 $ observes 및 $ watches는 모든 다이제스트주기 마다 점검됩니다 .
분리 범위가있는 지시문은 더 복잡합니다. '@'구문이 사용되면 보간 (예 : {{}})이 포함 된 DOM 속성을 $ observe 또는 $ watch 할 수 있습니다 . ($ watch와 함께 작동하는 이유는 '@'구문이 우리를 위해 보간 을 수행하기 때문에 $ watch는 {{}}없이 문자열을 볼 수 있기 때문입니다.) 이 경우에도 $ 관찰.
이 모든 것을 테스트하기 위해 두 가지 지시문을 정의 하는 Plunker 를 작성했습니다 . 하나 ( d1
)는 새 범위를 만들지 않고 다른 하나 ( d2
)는 격리 범위를 만듭니다. 각 지시문에는 동일한 6 개의 속성이 있습니다. 각 속성은 $ observe'd 및 $ watch'ed입니다.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
콘솔 로그를보고 연결 기능에서 $ observe와 $ watch의 차이점을 확인하십시오. 그런 다음 링크를 클릭하고 클릭 핸들러가 변경 한 속성에 의해 트리거되는 $ observes 및 $ watches를 확인하십시오.
링크 함수가 실행될 때 {{}}을 (를) 포함하는 속성은 아직 평가되지 않으므로 속성을 검사하려고하면을 얻게 undefined
됩니다. 보간 된 값을 보는 유일한 방법은 $ observe (또는 '@'와 함께 분리 범위를 사용하는 경우 $ watch)를 사용하는 것입니다. 따라서 이러한 속성 값을 가져 오는 것은 비동기 작업입니다. (그리고 이것이 $ observe 및 $ watch 함수가 필요한 이유입니다.)
때로는 $ observe 또는 $ watch가 필요하지 않습니다. 당신의 속성은 숫자 또는 부울 (안 문자열)이 포함 된 경우 예는 단 한 번 평가 : attr1="22"
, 당신의 연결 기능, 말,에 : var count = scope.$eval(attrs.attr1)
. 상수 문자열 인 경우 – attr1="my string"
– attrs.attr1
지시문에 사용 하십시오 ($ eval () 필요 없음).
$ watch 표현에 대한 Vojta의 Google 그룹 게시물 도 참조하십시오 .
ng-src/ng-href
사용 하는지 알고 있습니까? attr.$observe
scope.$watch
@
구문을 사용할 때 서로 호환됩니다 . 성능 차이는 없다고 생각하지만 실제 소스 코드는 보지 않았습니다.
귀하의 질문을 올바르게 이해하면 리스너 콜백을 등록 $watch
하거나로 할 경우 차이점이 무엇인지 묻습니다 $observe
.
에 등록 된 콜백 은 실행될 $watch
때 발생 $digest
합니다.
$observe
보간이 포함 된 속성의 값이 변경되면로 등록 된 콜백 이 호출됩니다 (예 :) attr="{{notJetInterpolated}}"
.
내부 지시문은 매우 비슷한 방식으로 두 가지를 모두 사용할 수 있습니다.
attrs.$observe('attrYouWatch', function() {
// body
});
또는
scope.$watch(attrs['attrYouWatch'], function() {
// body
});
$digest
단계적으로 반영 되므로 $observe
콜백이 에서 호출 될 것이라고 가정하는 것이 안전합니다 $digest
. 그리고 $watch
콜백도에서 호출됩니다 $digest
하지만 값이 될 때마다 변경됩니다. 나는 그들이 똑같은 일을하고 있다고 생각한다. 키워드 차이는 아마도 개발자를 혼동하지 않기위한 구문 설탕 일 것입니다.
나는 이것이 매우 명백하다고 생각한다.
명심하십시오 : 두 함수에는 두 가지 인수가 있습니다.
$observe/$watch(value : string, callback : function);
function (oldValue, newValue)
나는를 만들었 plunker으므로 실제로 두 활용도를 파악할 수 있습니다. 나는 그림을 더 쉽게 만들기 위해 카멜레온 유추를 사용했습니다.
$ observe가 $ watch와 다른 이유는 무엇입니까?
watchExpression이 평가되고 각 digest () 사이클의 이전 값과 비교됩니다. watchExpression 값에 변경이 있으면 watch 함수가 호출됩니다.
$ observe는 보간 된 값을 감시하기위한 것입니다. 지시문의 속성 값이 보간 된 경우 (예 dir-attr="{{ scopeVar }}"
:) 보간 된 값이 설정되어있을 때 ($ digest가 이미 업데이트를 수행해야한다고 결정한 경우) 관찰 함수가 호출됩니다. 기본적으로 보간에 대한 감시자가 이미 있으며 $ observe 함수는이를 피기 백합니다.
compile.js 에서 $ observe & $ set 참조