ProgramingTip

AngularJS에서 $ 범위. $ watch와 $ scope. $ 적용을 어떻게합니까?

bestdevel 2020. 9. 27. 13:18
반응형

AngularJS에서 $ 범위. $ watch와 $ scope. $ 적용을 어떻게합니까?


사용하는 방법 내가을 이해하지 않습니다 $scope.$watch$scope.$apply. 공식 문서는 도움이되지 않습니다.

내가 시체로 이해하지 못하는 것 :

  • DOM에 연결되어 있습니까?
  • 모델에 대한 DOM 변경 사항을 어떻게 업데이트 할 수 있습니까?
  • 그들 사이의 연결 지점은 무엇입니까?

노력 나는 이 튜토리얼을 하지만 이해합니다 $watch$apply부여에, 대한합니다.

을 무엇 $apply하고 무엇을 $watch하며 어떻게 적절하게 사용합니까?


AngularJS를 이해하기 어떻게 작동하는지 확인합니다.

다이제스트주기 및 $ 범위

AngularJS는 소위 다이제스트 사이클 의 개념을 정의합니다 . 이주 기는 AngularJS가 모든 s가 감시 하는 모든 변수에 변경 사항이 있는지 확인하는 루프로 처리 할 수 ​​있습니다 $scope. 따라서 $scope.myVar컨트롤러에서 정의 하고이 변수가 지켜표시된 경우 암시 적으로 AngularJS와에 myVar루프의 각 반복에서 변경 사항을 모니터링하도록 지시 하는을 구석으로입니다.

자연스러운 계속 질문은 다음과 가변합니다. 모든 것이 $scope감시 대상에 연결되어 있습니까? 아닙니다. 에서 모든 개체의 변경 사항을 $scope관찰하면 다이제스트 루프를 평가하는 데 시간이 오래 걸리고 성능 문제가 빠르게 발생합니다. 이것이 AngularJS 팀이 일부 $scope변수를 감시중인 것 선언하는 두 가지 방법을 제공합니다 (아래 참조).

$ watch는 $ scope 변화를 듣도록 도와줍니다.

$scope선언되는 변수를 선언하는 두 가지 방법이 있습니다 .

  1. 운영을 통해 템플릿에서 사용하여 <span>{{myVar}}</span>
  2. $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기능을 통합하여 생각할 수 있습니다 . 에 직접 object- 연결된$scope 일부 감시 변수 를 변경할 때마다 AngularJS와는 변경이 발생했음을 알게됩니다. AngularJS는 이미 존재하는 것입니다. 따라서 프레임 워크에서 관리하는 코드에서 발생하면 다이제스트주기가 계속됩니다.

그러나 AngularJS 세계 외부에서 일부 값변경 하고 변경 사항이 전달되는 것을보고 싶을 때 있습니다 . 이것을 고려하십시오 $scope.myVar-jQuery의 $.ajax()핸들러 내에서 수정 될 값이 있습니다 . 이 미래의 어느 시점에서 일어날 것입니다. AngularJS는 jQuery를 기다리라는 지시를받지 못해서 갑자기 일어날 때까지 기다릴 수 없습니다.

이를 해결하기 위해 $apply소개. 소화주기를 명시 적으로 시작할 수 있습니다. 일부 데이터를 AngularJS (다른 프레임 워크와 통합)로 마이그레이션하는 데만 사용하지만 AngularJS에서 오류가 발생하는 경우가있는 방법을 일반 AngularJS 코드와 결합하여 사용하지 않습니다.

이 모든 것이 DOM과 어떤 관련이 있습니까?

글쎄,이 모든 것을 알았으니 튜토리얼을 다시 따라야합니다. 다이제스트주기는 $scope변경 사항이없는 한 모든 경우 모든 감시 보안 평가하여 UI와 JavaScript 코드가 동기화 상태를 유지하는지 확인합니다 . 다이제스트 루프에서 더 이상 변경이 발생하지 않습니다.

$scope에서 명시 적 컨트롤러으로 또는 {{expression}}뷰에서 직접 형식 으로 선언 하여 개체 에 개체를 연결할 수 있습니다 .

이 모든 것에 대한 기본적인 지식을 좀 더 도움이됩니다.

추가 자료 :


AngularJS에서는 모델을 업데이트하고 뷰 / 템플릿은 내장 또는 사용자 지정 지시문을 통해 DOM을 "자동으로"업데이트합니다.

$ 적용 및 $ watch (둘 다 스코프 메소드 임)는 DOM과 관련이 없습니다.

개념 페이지 (섹션 "런타임")은 $ 소화 루프의 꽤 좋은 설명, $ 적용하는 $ evalAsync 큐와 $ 시계 목록이 있습니다. 다음은 텍스트와 함께 제공되는 그림입니다.

$ 다이제스트 루프

일반적으로 컨트롤러 및 지시문 (링크 함수 및 / 또는 해당 컨트롤러)에 대한 액세스 권한이있는 코드가 무엇이든 AngularJS가 해당하는 것에 대해 평가할 " watchExpression "을 접근 할 수 있습니다 . 이 평가는 AngularJS가 $ digest 루프 ( "$ watch list"에 때마다 발생합니다. 범위 속성을 관찰하고, 두 속성을 함께 관찰하는 함수를 정의 할 수 있고, 배열의 길이 등을 관찰 할 수 있습니다.

"AngularJS 내부"에서 일이 발생하면-예를 들어 AngularJS 양방향 데이터 바인딩이 활성화 된 (예 : ng-model 사용) 텍스트 상자에 입력하고 $ http가 실행됩니다.-$ apply가 이미 호출 되었으나 위 그림의 "AngularJS"사각형 안에 있습니다. (추가 변경 사항이 감지되지 않을 때까지 두 번 이상 가능).

"AngularJS 외부"에서 일이 발생하면 – 예를 들어, 지시문에서 bind ()를 사용 다음 해당 이벤트가 발생하여 호출되거나 일부 jQuery 등록 발생이 발생하는 경우 – 우리는 여전히 "Native"사각형에 있습니다. 코드가 $ watch 가보고있는 모든 것을 수정하는 경우 $ apply를 호출하여 AngularJS 사각형으로 $ digest 루프를 실행하면 AngularJS가 변경 사항을 감지하고 마법을 수행합니다.


AngularJS 와이 확장 이벤트 루프를 라는 뭔가를 만들어 AngularJS context.

$ 시계 ()

UI에서 때마다 바인드 뭔가 당신은 삽입 $watchA의 $watch목록 .

User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />

여기 $scope.user에는 첫 번째 입력에 바인딩 된, 두 번째 입력에 $scope.pass바인딩되어 있습니다. 이렇게하면 목록에 두 개의 $watches$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();
  });
}

http://jsfiddle.net/2Lyn0Lkb/

$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>

여기에 $watchng-click이 시계를 생성하지 않기 때문에 하나만 있습니다.

버튼을 누르십시오.

  1. 브라우저는 AngularJS 자주에 도움말 이벤트를받습니다.
  2. $digest루프가 실행되고 변경에 대한 모든 $ 시계를 요청합니다.
  3. 부터 $watch$ scope.name의 변화를 지켜보고 된이 변화를보고, 또 다른 $digest강제 루프.
  4. 새로운 루프는 아무것도보고하지 않습니다.
  5. 브라우저는 제어권을 되찾고 $ scope.name의 새 값을 반영하여 DOM을 업데이트합니다.
  6. Angular는 모든 이벤트가 $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캔버스, webGL 또는 서버 요청의 다른 뷰와 같이 dom 객체가 아닌 뷰에서 여러 속성을 가진 객체를 업데이트하는 함수를 호출하려는 경우 정말 유용합니다. 여기에서 문서 링크 .


위의 모든 것을 읽고 지루하고 졸리십시오 (미안하지만 사실입니다). 매우 기술적이고 깊이 있고 상세하며 건조합니다. 나는 왜 글을 쓰고 있는가? AngularJS는 방대하기 때문에 상호 연결된 많은 개념이 모든 사람을 미치게 만들 수 있습니다. 나는 종종 스스로에게 물었다. 나는 그것들을 이해할만큼 똑똑하지 않은가? 아니! 모든 용어를 사용하지 않고 간단한 언어로 기술을 설명 할 수있는 사람이 거의 없기 때문입니다 ! 좋습니다. 시도해 보겠습니다.

1) 그것들은 모두 이벤트 중심적인 것입니다. (웃음은 들리지만 계속 읽어)

이벤트 기반이 무엇인지 모르는 경우 페이지에 버튼을 배치한다고 생각하고 "on-click"을 사용하여 기능에 연결하고 사용자가 클릭하여 내부에 심은 작업을 트리거 할 때까지 기다립니다. 함수. 또는 SQL Server / Oracle의 "트리거"를 생각해보십시오.

2) $ watch는 "on-click"입니다.

특별한 점은 매개 변수로 2 개의 함수를 취하고, 첫 번째는 이벤트의 값을 제공하고, 두 번째는 값을 고려한다는 것입니다.

3) $ digest는 지칠 줄 모르는 주위를 확인하는 보스 , bla-bla-bla이지만 좋은 보스입니다.

4) $ apply는 실패 방지와 같이 수동으로 수행하려는 방법을 제공합니다 (클릭이 시작되지 않는 경우 강제로 실행합니다).

이제 화장으로 만들어 보겠습니다 . 사진 이 훨씬 더 쉽게 아이디어를 잡아 수 있도록 :

레스토랑에서,

-WAITERS 는 고객을 도와야합니다.

$watch(
  function(){return orders;},
  function(){Kitchen make it;}
);

-관리자 는 모든 웨이터가 깨어 있는지 확인하고 고객의 전화에 응답하는지 확인합니다. $digest()

-OWNER 는 요청시 모든 사람을 운전할 수 있습니다.$apply()

참고 URL : https://stackoverflow.com/questions/15112584/how-do-i-use-scope-watch-and-scope-apply-in-angularjs

반응형