내가 사용하는 방법을 이해하지 않습니다 $scope.$watch
와 $scope.$apply
. 공식 문서는 도움이되지 않습니다.
내가 구체적으로 이해하지 못하는 것 :
- 그들은 DOM에 연결되어 있습니까?
- 모델의 DOM 변경을 어떻게 업데이트합니까?
- 그들 사이의 연결점은 무엇입니까?
이 튜토리얼을 시도했지만 이해 $watch
하고 $apply
당연합니다.
무엇을 $apply
하고 $watch
어떻게, 그리고 그들을 적절하게 어떻게 사용합니까?
답변
AngularJS를 이해하려면 작동 방식에 대해 알고 있어야합니다.
다이제스트주기 및 $ scope
무엇보다도 AngularJS는 소위 다이제스트 사이클 의 개념을 정의합니다 . 이주기는 루프로 간주 될 수 있으며,이 과정에서 AngularJS는 모든 변수가 감시 하는 모든 변수에 변경 사항이 있는지 확인합니다 $scope
. 따라서 $scope.myVar
컨트롤러에서 정의 하고이 변수가 감시 대상으로 표시된myVar
경우 루프의 각 반복에서 변경 사항을 모니터링하도록 AngularJS에 암시 적으로 지시 합니다.
자연스러운 후속 질문은 다음과 같습니다. 모든 것이 $scope
감시 대상입니까? 다행히도 의 모든 객체에 대한 변경 사항을 관찰하려면 $scope
요약 루프가 평가하는 데 시간이 오래 걸리고 성능 문제가 빠르게 발생합니다. 이것이 AngularJS 팀이 $scope
변수를 감시하는 것으로 선언하는 두 가지 방법을 제공 한 이유입니다 (아래 참조).
$ watch는 $ scope 변경을 듣는 데 도움이됩니다.
$scope
변수를 감시하는 것으로 선언하는 두 가지 방법이 있습니다 .
- 표현식을 통해 템플리트에서이를 사용하여
<span>{{myVar}}</span>
$watch
서비스 를 통해 수동으로 추가
광고 1) 가장 일반적인 시나리오이며 이전에 본 적이 있지만 이것이 백그라운드에서 시계를 만들었다는 것을 몰랐습니다. 그렇습니다! AngularJS 지시문 (예 :)을 사용하면 ng-repeat
암시 적 시계를 만들 수도 있습니다.
광고 2) 자신 만의 시계 를 만드는 방법 입니다. $watch
서비스 $scope
는에 연결된 일부 값 이 변경 되었을 때 일부 코드를 실행하는 데 도움이됩니다 . 거의 사용되지 않지만 때때로 도움이됩니다. 예를 들어, ‘myVar’가 변경 될 때마다 일부 코드를 실행하려는 경우 다음을 수행 할 수 있습니다.
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ apply는 다이제스트 사이클과 변경 사항을 통합 할 수 있습니다
$apply
함수를 통합 메커니즘으로 생각할 수 있습니다 . 객체에 직접 연결된$scope
일부 감시 변수 를 변경할 때마다 AngularJS는 변경이 발생했음을 알게됩니다. AngularJS는 이러한 변경 사항을 모니터링하는 것을 이미 알고 있기 때문입니다. 따라서 프레임 워크가 관리하는 코드에서 발생하면 다이제스트주기가 계속됩니다.
그러나 때로는 AngularJS 세계 외부의 일부 값 을 변경 하고 변경 사항이 정상적으로 전파되는 것을보고 싶을 때가 있습니다 . 이것을 고려하십시오 $scope.myVar
-jQuery의 $.ajax()
핸들러 내에서 수정 될 값이 있습니다 . 이것은 미래에 일어날 것입니다. AngularJS는 jQuery를 기다리도록 지시받지 않았기 때문에 이것이 일어날 때까지 기다릴 수 없습니다.
이를 해결하기 위해 $apply
소개되었습니다. 다이제스트 사이클을 명시 적으로 시작할 수 있습니다. 그러나 일부 데이터를 AngularJS (다른 프레임 워크와의 통합)로 마이그레이션하는 데만 사용해야하지만 AngularJS는 오류를 발생시키기 때문에이 방법을 일반 AngularJS 코드와 결합하여 사용하지 마십시오.
이 모든 것이 DOM과 어떤 관련이 있습니까?
글쎄, 당신은 실제로 튜토리얼을 다시 따라야합니다. 이제 모든 것을 알았습니다. 다이제스트주기는 $scope
변경 사항이없는 한 모든 감시자에 연결된 모든 감시자를 평가하여 UI와 JavaScript 코드가 동기화 된 상태를 유지하도록합니다 . 다이제스트 루프에서 더 이상 변경이 발생하지 않으면 완료된 것으로 간주됩니다.
$scope
Controller에서 개체를 명시 적으로 또는 {{expression}}
보기에서 직접 형식 으로 선언 하여 개체에 연결할 수 있습니다 .
이 모든 것에 대한 기본 지식을 명확히하는 데 도움이되기를 바랍니다.
추가 자료 :
답변
AngularJS에서는 모델을 업데이트하고 뷰 / 템플릿은 DOM을 “자동으로”(내장 또는 사용자 지정 지시문을 통해) 업데이트합니다.
Scope 메소드 인 $ apply 및 $ watch는 DOM과 관련이 없습니다.
개념 페이지 (섹션 “런타임”)는 $ 소화 루프의 꽤 좋은 설명, $ 적용하는 $ evalAsync 큐와 $ 시계 목록이 있습니다. 텍스트와 함께 제공되는 그림은 다음과 같습니다.
범위에 액세스 할 수있는 코드 (일반적으로 컨트롤러 및 지시문 (그들의 링크 함수 및 / 또는 해당 컨트롤러)) 는 AngularJS가 해당 범위에 대해 평가할 ” watchExpression “을 설정할 수 있습니다 . 이 평가는 AngularJS가 $ digest 루프 (특히 “$ watch list”루프)에 들어갈 때마다 발생합니다. 개별 스코프 속성을 볼 수 있고, 두 속성을 함께 볼 수있는 함수를 정의하고, 배열의 길이 등을 볼 수 있습니다.
상황이 “AngularJS 내부에서”발생하는 경우 – 예를 들어 AngularJS 양방향 데이터 바인딩이 활성화 된 텍스트 상자에 입력 (예 : ng-model 사용), $ http 콜백 발생 등 – $ apply가 이미 호출되었으므로 위 그림의 “AngularJS”사각형 안에 있습니다. 모든 watchExpression이 평가됩니다 (추가 변경이 감지되지 않을 때까지 두 번 이상 가능).
예를 들어 지시문에서 bind ()를 사용한 다음 이벤트가 발생하여 콜백이 발생하거나 jQuery에 등록 된 콜백이 발생하는 등 AngularJS 외부에서 상황이 발생하면 여전히 “기본”사각형에있게됩니다. 콜백 코드가 $ watch가보고있는 것을 수정하면 $ apply를 호출하여 AngularJS 사각형으로 들어가서 $ digest 루프가 실행되므로 AngularJS는 변경 사항을 확인하고 그 마법을 수행합니다.
답변
AngularJS는이 events-loop을 확장하여 이라는 것을 만듭니다 AngularJS context
.
$ watch ()
UI에서 무언가를 바인딩 할 때마다 목록 $watch
에 a$watch
를 삽입 합니다 .
User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />
여기 $scope.user
에 첫 번째 입력에 바인딩되어 있고 두 번째 입력에 $scope.pass
바인딩되어 있습니다. 이렇게하면 목록에 두 개의 $watch
es$watch
가 추가 됩니다 .
우리의 경우 템플릿이 로드, 일명 연결 단계에서, 컴파일러는 모든 지시를 찾아 모든 생성 할 $watch
필요 말이지.
AngularJS와는 제공 $watch
, $watchcollection
및 $watch(true)
. 아래는 감시자 로부터 얻은 세 가지를 모두 자세히 설명하는 깔끔한 다이어그램 입니다.
angular.module('MY_APP', []).controller('MyCtrl', MyCtrl)
function MyCtrl($scope,$timeout) {
$scope.users = [{"name": "vinoth"},{"name":"yusuf"},{"name":"rajini"}];
$scope.$watch("users", function() {
console.log("**** reference checkers $watch ****")
});
$scope.$watchCollection("users", function() {
console.log("**** Collection checkers $watchCollection ****")
});
$scope.$watch("users", function() {
console.log("**** equality checkers with $watch(true) ****")
}, true);
$timeout(function(){
console.log("Triggers All ")
$scope.users = [];
$scope.$digest();
console.log("Triggers $watchCollection and $watch(true)")
$scope.users.push({ name: 'Thalaivar'});
$scope.$digest();
console.log("Triggers $watch(true)")
$scope.users[0].name = 'Superstar';
$scope.$digest();
});
}
$digest
고리
브라우저가 AngularJS 컨텍스트에서 관리 할 수있는 이벤트를 수신하면 $digest
루프가 시작됩니다. 이 루프는 두 개의 작은 루프로 구성됩니다. 하나는 $evalAsync
대기열을 처리하고 다른 하나 는 대기열을 처리합니다 $watch list
. $digest
의 목록을 의지 루프 $watch
우리가 가지고
app.controller('MainCtrl', function() {
$scope.name = "vinoth";
$scope.changeFoo = function() {
$scope.name = "Thalaivar";
}
});
{{ name }}
<button ng-click="changeFoo()">Change the name</button>
$watch
ng-click은 시계를 만들지 않기 때문에 여기에는 하나만 있습니다.
우리는 버튼을 누릅니다.
- 브라우저는 AngularJS 컨텍스트로 들어갈 이벤트를받습니다.
$digest
루프가 실행됩니다 및 변경에 대한 모든 $ 시계를 요청합니다.- 부터
$watch
$ scope.name의 변화를 지켜보고 된이 변화를보고, 그것은 또 다른 강제$digest
루프. - 새로운 루프는 아무 것도보고하지 않습니다.
- 브라우저는 제어권을 다시 얻고 $ scope.name의 새로운 값을 반영하여 DOM을 업데이트합니다.
- 여기서 중요한 것은 AngularJS 컨텍스트에 들어가는 모든 이벤트가
$digest
루프 를 실행한다는 것 입니다. 즉, 입력에 문자를 쓸 때마다 루프$watch
가이 페이지의 모든 항목 을 검사 합니다.
$ apply ()
$apply
이벤트가 시작될 때 전화를 걸면 각도 컨텍스트를 통과하지만 전화를 걸지 않으면 외부에서 실행됩니다. 그렇게 쉽습니다. 내부적으로 루프 $apply
를 호출하고$digest()
DOM이 새로 업데이트 된 값으로 업데이트되도록 모든 시계를 반복합니다.
이 $apply()
방법은 전체 $scope
체인 에서 감시자를 트리거 하는 반면 $digest()
, 현재 $scope
및 그 감시자 만 트리거 합니다 children
. 상위 $scope
개체가 로컬 변경 사항에 대해 알 필요가없는 경우을 사용할 수 있습니다 $digest()
.
답변
나는 어떤 커버 매우 깊이있는 영상을 발견 $watch
, $apply
, $digest
과에 사이클을 소화 :
다음은 해당 비디오에서 개념을 설명하기 위해 사용되는 두 개의 슬라이드입니다 (위의 링크가 제거되거나 작동하지 않는 경우에 대비).
위 이미지에서 “$ scope.c”는 데이터 바인딩 (마크 업)에 사용되지 않으므로 감시되지 않습니다. 다른 두 개 ( $scope.a
및 $scope.b
)가 감시됩니다.
위의 이미지에서 : AngularJS는 해당 브라우저 이벤트를 기반으로 이벤트를 캡처하고 다이제스트주기를 수행하고 (변경 사항이있는 모든 시계를 통과) 시계 기능을 실행하고 DOM을 업데이트합니다. 그렇지 않으면 브라우저 이벤트는, 다이제스트주기는 수동으로 사용하여 트리거 할 수 있습니다 $apply
또는 $digest
.
에 대한 자세한 $apply
과 $digest
:
답변
있다 $watchGroup
및 $watchCollection
뿐만 아니라. 특히, $watchGroup
dom 객체가 아닌 뷰에 여러 속성이있는 객체를 업데이트하는 함수 (예 : canvas의 다른 뷰, WebGL 또는 서버 요청) 를 업데이트하려는 경우 실제로 유용합니다 .
여기에 문서 링크가 있습니다.
답변
위의 모든 내용을 읽은 후 지루하고 졸리십시오 (죄송하지만 사실입니다). 매우 기술적이고 깊이 있고 상세하며 건조합니다. 내가 왜 쓰는거야? AngularJS는 방대하기 때문에 많은 상호 연결된 개념으로 인해 누구나 쉽게 갈 수 있습니다. 나는 종종 나 자신에게 물었다. 나는 그들을 이해할만큼 똑똑하지 않은가? 아니! 모든 용어 없이 기술을 설명 할 수있는 사람은 거의 없기 때문입니다 ! 알겠습니다.
1) 그것들은 모두 이벤트 중심의 것입니다. (웃음은 들었지만 계속 읽습니다)
이벤트 중심이 무엇인지 모른다면 페이지에 단추를 놓은 다음 “온 클릭”기능을 사용하여 단추를 클릭하고 사용자가 단추를 클릭하여 함수. 또는 SQL Server / Oracle의 “트리거”를 생각하십시오.
2) $ watch는 “클릭시”입니다.
특별한 점은 두 가지 기능을 매개 변수로 사용한다는 것입니다. 첫 번째는 이벤트에서 값을 제공하고 두 번째는 값을 고려합니다 …
3) $ digest는 지칠 줄 모르고 주위를 점검 하는 보스입니다.
4) $ apply는 실패 방지와 같이 수동으로 수행 할 때 방법을 제공합니다 (클릭시 킥이 발생하지 않으면 강제로 실행).
이제 시각적으로 만들어 봅시다. 아이디어를 더 쉽게 잡을 수 있도록 이것을 묘사하십시오.
레스토랑 안에,
-웨이터
고객으로부터 주문을 받아야합니다.
$watch(
function(){return orders;},
function(){Kitchen make it;}
);
– MANAGER 확인 모든 웨이터가 고객의 변화의 징후에 반응, 깨어하게 돌아 다니고. 이것은$digest()
-OWNER 는 요청에 따라 모든 사람을 운전할 수있는 최고의 힘을 가지고 있습니다.$apply()