AngularJS
다이제스트 루프 둘러보기
수색…
통사론
- $ scope. $ watch (watchExpression, callback, [deep compare])
- $ scope. $ digest ()
- $ 범위. $ 적용 ([exp])
양방향 데이터 바인딩
Angular는 후드 아래서 어떤 마법을 가지고 있습니다. DOM 을 실제 js 변수에 바인딩 할 수 있습니다.
Angular는 변수를 변경 한 후에 호출되는 " 다이제스트 루프 "라는 루프를 사용합니다. DOM을 업데이트하는 콜백을 호출합니다.
예를 들어, ng-model
지시문은 keyup
eventListener 를이 입력에 연결합니다.
<input ng-model="variable" />
keyup
이벤트가 발생할 때마다 다이제스트 루프 가 시작됩니다.
어느 시점에서 다이제스트 루프 는이 범위의 내용을 업데이트하는 콜백을 반복합니다.
<span>{{variable}}</span>
이 예제의 기본적인 생명주기는 각양이 어떻게 작동하는지 요약합니다 (매우 개략적으로).
- 각도 스캔 html
-
ng-model
지시문은 생성keyup
입력에 청취자 - 범위 내
expression
은 다이제스트주기에 대한 콜백을 추가합니다.
-
- 사용자가 입력과 상호 작용합니다.
-
keyup
수신기가 다이제스트주기를 시작 합니다. - 다이제스트 사이클 은 콜백을 호출합니다.
- 콜백 업데이트 범위
-
$ digest와 $ watch
이전 예제의 결과를 얻으려면 양방향 데이터 바인딩을 구현하는 두 가지 핵심 기능을 수행 할 수 있습니다.
- $ digest 는 사용자 상호 작용 후에 호출됩니다 (DOM => 변수 바인딩).
- $ watch 변수는 변수 변경 후 호출되도록 콜백을 설정합니다 (binding variable => DOM).
참고 : 이것은 실제 각도 코드가 아닌 데모입니다.
<input id="input"/>
<span id="span"></span>
우리가 필요로하는 두 가지 기능 :
var $watches = [];
function $digest(){
$watches.forEach(function($w){
var val = $w.val();
if($w.prevVal !== val){
$w.callback(val, $w.prevVal);
$w.prevVal = val;
}
})
}
function $watch(val, callback){
$watches.push({val:val, callback:callback, prevVal: val() })
}
이제 우리는이 함수를 사용하여 DOM에 변수를 연결시킬 수 있습니다 (각도는 내장 된 지시문을 사용하여 수행 할 수 있습니다).
var realVar;
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
realVar=e.target.value;
$digest()
}, true);
//this is usually done with {{expressions}} or ng-bind directive
$watch(function(){return realVar},function(val){
span1.innerHTML = val;
});
물론, 실제 구현은 더 복잡하며 바인딩 할 요소 와 사용할 변수 를 지원합니다.
실행중인 예제는 다음에서 찾을 수 있습니다. https://jsfiddle.net/azofxd4j/
$ 범위 트리
이전 예는 단일 HTML 요소를 단일 변수에 바인딩해야 할 때 충분합니다.
실제로 우리는 많은 요소를 여러 변수에 바인딩해야합니다.
<span ng-repeat="number in [1,2,3,4,5]">{{number}}</span>
이 ng-repeat
5 개 요소를 number
라는 5 개의 변수에 바인딩합니다. 각각의 값은 서로 다릅니다.
각도가이 동작을 달성하는 방법은 별도의 변수가 필요한 각 요소에 별도의 컨텍스트를 사용하는 것입니다. 이 컨텍스트를 범위라고합니다.
각 범위는 DOM에 바인딩 된 변수 인 속성을 포함하고 $digest
및 $watch
함수는 범위의 메서드로 구현됩니다.
DOM은 트리이며 트리의 여러 수준에서 변수를 사용해야합니다.
<div>
<input ng-model="person.name" />
<span ng-repeat="number in [1,2,3,4,5]">{{number}} {{person.name}}</span>
</div>
그러나 우리가 보았 듯이, ng-repeat
내의 변수의 컨텍스트 (또는 범위)는 그 위의 컨텍스트와 다릅니다. 이를 해결하기 위해 스코프를 트리 형태로 구현합니다.
각각의 범위는 아이들의 배열을 가지고 있으며, 그 호출 $digest
방법은 그 아이의 모든 실행 $digest
방법.
이 방법은 - 입력을 변경 한 후에 - $digest
는 div의 범위에 대해 호출되고, 그 다음 5 명의 자식에 대해 $digest
가 실행되어 내용을 업데이트합니다.
범위에 대한 간단한 구현은 다음과 같이 보일 수 있습니다.
function $scope(){
this.$children = [];
this.$watches = [];
}
$scope.prototype.$digest = function(){
this.$watches.forEach(function($w){
var val = $w.val();
if($w.prevVal !== val){
$w.callback(val, $w.prevVal);
$w.prevVal = val;
}
});
this.$children.forEach(function(c){
c.$digest();
});
}
$scope.prototype.$watch = function(val, callback){
this.$watches.push({val:val, callback:callback, prevVal: val() })
}
참고 : 이것은 실제 각도 코드가 아닌 데모입니다.