답변:
AngularJS를 이해하려면 작동 방식에 대해 알고 있어야합니다.
무엇보다도 AngularJS는 소위 다이제스트 사이클 의 개념을 정의합니다 . 이주기는 루프로 간주 될 수 있으며,이 과정에서 AngularJS는 모든 변수가 감시 하는 모든 변수에 변경 사항이 있는지 확인합니다 $scope
. 따라서 $scope.myVar
컨트롤러에서 정의 하고이 변수가 감시 대상으로 표시된myVar
경우 루프의 각 반복에서 변경 사항을 모니터링하도록 AngularJS에 암시 적으로 지시 합니다.
자연스러운 후속 질문은 다음과 같습니다. 모든 것이 $scope
감시 대상입니까? 다행히도 의 모든 객체에 대한 변경 사항을 관찰하려면 $scope
요약 루프가 평가하는 데 시간이 오래 걸리고 성능 문제가 빠르게 발생합니다. 이것이 AngularJS 팀이 $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
함수를 통합 메커니즘으로 생각할 수 있습니다 . 객체에 직접 연결된$scope
일부 감시 변수 를 변경할 때마다 AngularJS는 변경이 발생했음을 알게됩니다. AngularJS는 이러한 변경 사항을 모니터링하는 것을 이미 알고 있기 때문입니다. 따라서 프레임 워크가 관리하는 코드에서 발생하면 다이제스트주기가 계속됩니다.
그러나 때로는 AngularJS 세계 외부의 일부 값 을 변경 하고 변경 사항이 정상적으로 전파되는 것을보고 싶을 때가 있습니다 . 이것을 고려하십시오 $scope.myVar
-jQuery의 $.ajax()
핸들러 내에서 수정 될 값이 있습니다 . 이것은 미래에 일어날 것입니다. AngularJS는 jQuery를 기다리도록 지시받지 않았기 때문에 이것이 일어날 때까지 기다릴 수 없습니다.
이를 해결하기 위해 $apply
소개되었습니다. 다이제스트 사이클을 명시 적으로 시작할 수 있습니다. 그러나 일부 데이터를 AngularJS (다른 프레임 워크와의 통합)로 마이그레이션하는 데만 사용해야하지만 AngularJS는 오류를 발생시키기 때문에이 방법을 일반 AngularJS 코드와 결합하여 사용하지 마십시오.
글쎄, 당신은 실제로 튜토리얼을 다시 따라야합니다. 이제 모든 것을 알았습니다. 다이제스트주기는 $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는 변경 사항을 확인하고 그 마법을 수행합니다.
scope.$apply(scope.model)
. 어떤 데이터가 전송되는지 이해하고 모델의 올바른 위치로 어떻게 전송됩니까?
scope.$apply(scope.model)
간단히 scope.model
Angular 표현식으로 평가 한 다음 $ digest 루프를 입력하십시오. 참조하는 기사 scope.$apply()
에서 모델은 이미 $ watch'ed이므로 충분할 것입니다. stop () 함수가 모델을 업데이트 중입니다 (toUpdate는 scope.model에 대한 참조라고 생각합니다), $ apply가 호출됩니다.
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은 시계를 만들지 않기 때문에 여기에는 하나만 있습니다.
우리는 버튼을 누릅니다.
$digest
루프가 실행됩니다 및 변경에 대한 모든 $ 시계를 요청합니다.$watch
$ scope.name의 변화를 지켜보고 된이 변화를보고, 그것은 또 다른 강제 $digest
루프.$digest
루프 를 실행한다는 것 입니다. 즉, 입력에 문자를 쓸 때마다 루프 $watch
가이 페이지의 모든 항목 을 검사 합니다.$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 또는 서버 요청) 를 업데이트하려는 경우 실제로 유용합니다 .
여기에 문서 링크가 있습니다.
$watchCollection
그러나 나는 당신이 이미 한 것을 보았습니다. 다음은 AngularJS 사이트에서 이에 대한 설명서 입니다. 그들은 $watch
깊이에 대한 아주 좋은 시각을 제공합니다 . 정보는 페이지 하단에 가깝습니다.
위의 모든 내용을 읽은 후 지루하고 졸리십시오 (죄송하지만 사실입니다). 매우 기술적이고 깊이 있고 상세하며 건조합니다. 내가 왜 쓰는거야? AngularJS는 방대하기 때문에 많은 상호 연결된 개념으로 인해 누구나 쉽게 갈 수 있습니다. 나는 종종 나 자신에게 물었다. 나는 그들을 이해할만큼 똑똑하지 않은가? 아니! 모든 용어 없이 기술을 설명 할 수있는 사람은 거의 없기 때문입니다 ! 알겠습니다.
1) 그것들은 모두 이벤트 중심의 것입니다. (웃음은 들었지만 계속 읽습니다)
이벤트 중심이 무엇인지 모른다면 페이지에 단추를 놓은 다음 "온 클릭"기능을 사용하여 단추를 클릭하고 사용자가 단추를 클릭하여 함수. 또는 SQL Server / Oracle의 "트리거"를 생각하십시오.
2) $ watch는 "클릭시"입니다.
특별한 점은 두 가지 기능을 매개 변수로 사용한다는 것입니다. 첫 번째는 이벤트에서 값을 제공하고 두 번째는 값을 고려합니다 ...
3) $ digest는 지칠 줄 모르고 주위를 점검 하는 보스입니다.
4) $ apply는 실패 방지와 같이 수동으로 수행 할 때 방법을 제공합니다 (클릭시 킥이 발생하지 않으면 강제로 실행).
이제 시각적으로 만들어 봅시다. 아이디어를 더 쉽게 잡을 수 있도록 이것을 묘사하십시오.
레스토랑 안에,
-웨이터
고객으로부터 주문을 받아야합니다.
$watch(
function(){return orders;},
function(){Kitchen make it;}
);
- MANAGER 확인 모든 웨이터가 고객의 변화의 징후에 반응, 깨어하게 돌아 다니고. 이것은$digest()
-OWNER 는 요청에 따라 모든 사람을 운전할 수있는 최고의 힘을 가지고 있습니다.$apply()