나는 모두 알고 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 객체의 메소드이므로 스코프 객체에 액세스 할 수있는 모든 곳에서 사용 / 호출 할 수 있습니다.
- 컨트롤러-모든 컨트롤러-ng-view, ng-controller 또는 지시어 컨트롤러를 통해 생성 된 컨트롤러
- 지시문의 연결 함수. 범위에 대한 액세스 권한도 있기 때문에
문자열은 각도 식으로 평가되므로 모델 / 범위 속성을 관찰 / 감시 할 때 $ 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 그룹 게시물 도 참조하십시오 .
답변
귀하의 질문을 올바르게 이해하면 리스너 콜백을 등록 $watch
하거나로 할 경우 차이점이 무엇인지 묻습니다 $observe
.
에 등록 된 콜백 은 실행될 $watch
때 발생 $digest
합니다.
$observe
보간이 포함 된 속성의 값이 변경되면로 등록 된 콜백 이 호출됩니다 (예 🙂 attr="{{notJetInterpolated}}"
.
내부 지시문은 매우 비슷한 방식으로 두 가지를 모두 사용할 수 있습니다.
attrs.$observe('attrYouWatch', function() {
// body
});
또는
scope.$watch(attrs['attrYouWatch'], function() {
// body
});
답변
나는 이것이 매우 명백하다고 생각한다.
- $ observe는 지시문의 기능을 연결하는 데 사용됩니다.
- $ watch는 범위에서 값의 변화를 보는 데 사용됩니다.
명심하십시오 : 두 함수에는 두 가지 인수가 있습니다.
$observe/$watch(value : string, callback : function);
- value : 감시 대상 요소에 대한 문자열 참조입니다 (범위 변수 이름 또는 감시 할 지시문 속성 이름).
- 콜백 : 폼에서 실행될 함수
function (oldValue, newValue)
나는를 만들었 plunker으므로 실제로 두 활용도를 파악할 수 있습니다. 나는 그림을 더 쉽게 만들기 위해 카멜레온 유추를 사용했습니다.
답변
$ observe가 $ watch와 다른 이유는 무엇입니까?
watchExpression이 평가되고 각 digest () 사이클의 이전 값과 비교됩니다. watchExpression 값에 변경이 있으면 watch 함수가 호출됩니다.
$ observe는 보간 된 값을 감시하기위한 것입니다. 지시문의 속성 값이 보간 된 경우 (예 dir-attr="{{ scopeVar }}"
🙂 보간 된 값이 설정되어있을 때 ($ digest가 이미 업데이트를 수행해야한다고 결정한 경우) 관찰 함수가 호출됩니다. 기본적으로 보간에 대한 감시자가 이미 있으며 $ observe 함수는이를 피기 백합니다.
compile.js 에서 $ observe & $ set 참조