디렉티브 테스트에서 $ apply 대 $ digest


98

범위에있는 특정 속성의 상태에 응답하는 지시문이 있고 테스트에서 해당 속성을 변경하고 올바르게 응답하는지 확인하려는 경우 변경을 수행하는 가장 좋은 방법은 무엇입니까?

이 두 패턴을 모두 보았습니다.

scope.$apply(function() {
    scope.myAttribute = true;
});

scope.myAttribute = true;
scope.$digest();

그들 사이의 차이점은 무엇이며 어떤 것이 더 낫고 그 이유는 무엇입니까?

답변:


206

scope.$digest()현재 범위와 모든 하위 항목에서도 감시자를 발사합니다. scope.$apply전달 된 함수를 평가하고 $rootScope.$digest().

첫 번째는 현재 범위와 그 하위에 대한 감시자를 평가해야하기 때문에 더 빠릅니다. 두 번째는 감시자 $rootScope와 모든 하위 범위 를 평가해야하기 때문에 더 느립니다 .

감시자 중 하나에서 오류가 발생하여를 사용하면 서비스 scope.$digest를 통해 처리되지 않으므로 $exceptionHandler직접 예외를 처리해야합니다. 내부적 scope.$apply으로 try-catch블록을 사용하고 모든 예외를 $exceptionHandler.


1
$digest도 범위의 어린이라고?
pilau

15
이것은 오해의 소지가 있습니다. $digest현재 범위의 감시자뿐만 아니라 모든 자식에게도 화재를 일으 킵니다.
tasseKATT 2014

@tasseKATT, 귀하의 의견이 제안하는 것을 캡처 한 것 같습니다.
activedecay

12

문서 자체에 언급 된 것처럼 $ digest주기는 언제든지 수행 $scope.$apply됩니다. 범위 에 대한 개발자 가이드에 따라

식을 평가 한 후 $ apply 메서드는 $ digest를 수행합니다. $ digest 단계에서 스코프는 모든 $ watch 표현식을 검사하고 이전 값과 비교합니다.

그리고 Scope API 문서에 따라

일반적으로 컨트롤러 또는 지시문에서 직접 $ digest ()를 호출하지 않습니다. 대신 $ apply ()를 호출하면 (일반적으로 지시문 내에서) $ digest ()가 강제 실행됩니다.

따라서 명시 적으로를 호출해서는 안되며 메서드 $digest를 호출 $apply하면 다이제스트주기가 트리거됩니다.


8
현재 범위와 하위 항목 만 평가해야하는 대부분의 경우 다이제스트가 충분하므로 이는 사실이 아닙니다. . $ 범위 $ 통화가 $ 내부적으로 소화 적용하는 것이 사실이지만, $ rootScope를 호출 끝날 것 기억하는 것이 매우 중요합니다 $는 따라서 매우 무거운 (소화)합니다.
Srivathsa Harish Venkataramana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.