여러 $ scope 속성보기


답변:


586

AngularJS 1.3부터는 $watchGroup표현식 세트를 관찰하는 새로운 메소드가 있습니다.

$scope.foo = 'foo';
$scope.bar = 'bar';

$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
  // newValues array contains the current values of the watch expressions
  // with the indexes matching those of the watchExpression array
  // i.e.
  // newValues[0] -> $scope.foo 
  // and 
  // newValues[1] -> $scope.bar 
});

7
$ watchCollection ( '[a, b]')와의 차이점은 무엇입니까 ??
— Kamil Tomšík

28
차이점은 배열처럼 보이는 문자열 대신 적절한 배열을 사용할 수 있다는 것입니다.
— Paolo Moretti

2
비슷한 문제가 있었지만 controllerAs 패턴을 사용하고 있습니다. 내 경우에는 수정 사항이 변수 이름 앞에 컨트롤러 이름으로 구성되었습니다.$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
— morels

1
Angular 1.6에서는 작동하지 않는 것 같습니다. 함수에 콘솔 로그를 넣으면 속성 이 정상적으로 작동하는 것을 보면서 개별 로 newValues및 oldValuesas로 한 번만 실행되는 것을 볼 수 있습니다 undefined.
— Alejandro García Iglesias

290

AngularJS 1.1.4부터 다음을 사용할 수 있습니다 $watchCollection.

$scope.$watchCollection('[item1, item2]', function(newValues, oldValues){
    // do stuff here
    // newValues and oldValues contain the new and respectively old value
    // of the observed collection array
});

플런저 예제는 여기

여기에 문서


109
첫 번째 매개 변수는 배열 이 아닙니다 . 배열처럼 보이는 문자열입니다.
— MK Safi

1
이것에 감사합니다. 나를 위해 작동하는 경우에, 나는 당신에게 천 금화를 줄 것이다 - 가상 사람을 :) 물론
— AdityaSaxena

5
분명한 것은 (실제로 몇 분이 걸렸음) $watchCollection객체를 전달하고 객체의 속성에 대한 변경 사항을 감시하는 반면, $watchGroup변경 사항을 감시하기 위해 개별 속성 배열을 전달하는 것입니다. 비슷하지만 다른 문제를 해결하기 위해 약간 다릅니다. 휴!
— Mattygabe

1
:이 방법을 사용하면 어떻게 든, newValues 및 oldValues는 항상 동일 plnkr.co/edit/SwwdpQcNf78pQ80hhXMr
— mostruash

감사. 내 문제를 해결했습니다. $ watch 사용시 성능 저하 / 문제가 있습니까?
— Syed Nasir Abbas

118

$watch 첫 번째 매개 변수는 함수일 수도 있습니다.

$scope.$watch(function watchBothItems() {
  return itemsCombinedValue();
}, function whenItemsChange() {
  //stuff
});

결합 된 두 값이 단순하면 첫 번째 매개 변수는 일반적으로 각도 표현식입니다. 예를 들어 firstName과 lastName은 다음과 같습니다.

$scope.$watch('firstName + lastName', function() {
  //stuff
});

8
이것은 기본적으로 프레임 워크에 포함되기를 요구하는 유스 케이스처럼 보입니다. 계산 된 속성조차도 간단한 fullName = firstName + " " + lastName인수가 아닌 첫 번째 인수로 함수를 전달해야합니다 'firstName, lastName'. Angular는 매우 강력하지만 성능이나 디자인 원칙을 훼손하지 않는 방식으로 개발자에게 더 친숙한 영역이 있습니다.
— XML

4
글쎄 $ watch는 각도 표현을 취합니다.이 표현식은 호출 된 범위에서 평가됩니다. 그래서 당신은 할 수 있습니다 $scope.$watch('firstName + lastName', function() {...}). 시계를 두 개만 사용할 수도 있습니다 function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);.. 간단한 사례를 답변에 추가했습니다.
— 앤드류 조슬린

'firstName + lastName'의 플러스는 문자열 연결입니다. 따라서 각도는 단지 연결 결과가 다른지 여부를 확인합니다.
— mb21

16
문자열 연결에는 약간의주의가 필요합니다. "paran orman"을 "para norman"으로 변경하면 응답을 트리거하지 않습니다. 최종있는 제 1 및 제 2 기간 사이 | "\ t \ t", 또는 JSON 그냥 스틱 최고의 같은 디바이더를 넣어
— 데이브 Edelhart

amberjs는 짜증나지만이 기능이 내장되어 있습니다! 저 남자들을 들으세요 시계를하는 것이 가장 합리적인 방법이라고 생각합니다.
— Aladdin Mhemed

70

다음은 실제로 작동하는 원래 의사 코드와 매우 유사한 솔루션입니다.

$scope.$watch('[item1, item2] | json', function () { });

편집 : 좋아, 나는 이것이 더 낫다고 생각한다.

$scope.$watch('[item1, item2]', function () { }, true);

기본적으로 우리는 멍청한 것처럼 보이는 json 단계를 건너 뛰지 만 그것이 없으면 작동하지 않았습니다. 이 키는 종종 생략되는 3 번째 매개 변수로, 참조 평등과 반대로 객체 평등을 켭니다. 그런 다음 생성 된 배열 객체 간의 비교가 실제로 올바르게 작동합니다.


나는 비슷한 질문을했다. 그리고 이것은 저에게 정답입니다.
— Calvin Cheng

배열 표현식의 항목이 단순한 유형이 아닌 경우 둘 다 약간의 성능 오버 헤드가 있습니다.
— null

사실입니다. 구성 요소 개체를 전체 깊이 비교하고 있습니다. 당신이 원하는 것일 수도 아닐 수도 있습니다. 전체 깊이 비교를하지 않는 최신 각도를 사용하는 버전에 대해서는 현재 승인 된 답변을 참조하십시오.
— Karen Zilles

어떤 이유로 배열에서 $ watchCollection을 사용하려고 할 때이 오류가 발생 TypeError: Object #<Object> has no method '$watchCollection'했지만이 솔루션은 내 문제를 해결하는 데 도움이됩니다!
— abottoni

쿨, 당신은 개체 내에서 값을 볼 수 있습니다 :$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
— Serge van den Oever

15

$ watchGroup의 함수를 사용하여 범위 내 객체의 필드를 선택할 수 있습니다.

        $scope.$watchGroup(
        [function () { return _this.$scope.ViewModel.Monitor1Scale; },   
         function () { return _this.$scope.ViewModel.Monitor2Scale; }],  
         function (newVal, oldVal, scope) 
         {
             if (newVal != oldVal) {
                 _this.updateMonitorScales();
             }
         });

1
왜 사용 _this합니까? 스코프가 명시 적으로 정의하지 않고 함수로 전달되지 않습니까?
— sg.cc

1
typescript를 사용하면 제시된 코드가 컴파일 된 결과입니다.
— Yang Zhang

12

왜 그것을 단순히 포장하지 forEach않습니까?

angular.forEach(['a', 'b', 'c'], function (key) {
  scope.$watch(key, function (v) {
    changed();
  });
});

실제로 값 구성에 대해 걱정할 필요없이 결합 된 값에 대한 기능을 제공하는 것과 거의 동일한 오버 헤드 입니다.


이 경우 log ()가 여러 번 실행됩니다. 중첩 된 $ watch 함수의 경우에는 그렇지 않을 것이라고 생각합니다. 그리고 여러 속성을 한 번에 보는 솔루션에는 없어야합니다.
— John Doe

아니요, 감시 속성 당 변경 당 한 번만 로그가 실행됩니다. 왜 여러 번 호출됩니까?
— Erik Aigner

맞아요. 우리 모두를 동시에보고 싶다면 좋지 않을 것입니다.
— John Doe

1
왜 안돼? 나는 내 프로젝트에서 그렇게합니다. changed()속성 중 하나에서 무언가가 변경 될 때마다 호출됩니다. 그것은 결합 된 값을위한 함수가 제공되는 것과 똑같은 동작입니다.
— Erik Aigner

1
배열의 여러 항목이 동시에 변경되면 $ watch는 변경된 항목 당 한 번이 아니라 한 번만 핸들러를 실행한다는 점에서 약간 다릅니다.
— bingles

11

값을 결합하는 약간 더 안전한 솔루션은 다음을 $watch함수 로 사용하는 것입니다.

function() { return angular.toJson([item1, item2]) }

또는

$scope.$watch(
  function() {
    return angular.toJson([item1, item2]);
  },
  function() {
    // Stuff to do after either value changes
  });

5

$ watch first 매개 변수는 각도 표현식 또는 함수일 수 있습니다 . $ scope. $ watch 설명서를 참조하십시오 . 여기에는 $ watch 메소드 작동 방식에 대한 유용한 정보가 많이 포함되어 있습니다. watchExpression이 호출 될 때, 각도가 결과를 비교하는 방법 등


4

어때요?

scope.$watch(function() { 
   return { 
      a: thing-one, 
      b: thing-two, 
      c: red-fish, 
      d: blue-fish 
   }; 
}, listener...);

2
익명 해시가 매번 다른 참조를 갖기 때문에 trueto 에서 세 번째 매개 변수를 사용 하지 않으면 scope.$watch(예와 같이) listener()매번 실행됩니다.
— Peter V. Mørch

이 솔루션이 내 상황에 효과적이라는 것을 알았습니다. 나에게는 더 비슷했다 return { a: functionA(), b: functionB(), ... }. 그런 다음 새 값과 이전 값의 반환 된 객체를 서로 비교합니다.
— RevNoah

4
$scope.$watch('age + name', function () {
  //called when name or age changed
});

여기서 나이와 이름 값이 모두 변경되면 함수가 호출됩니다.


2
또한이 경우 앵귤러가 콜백에 전달되는 newValue 및 oldValue 인수는 변경 한 필드가 아니라 결과로 연결되므로 사용하지 마십시오.
— Akash Shinde

1

$watchGroup버전 1.3에 도입 된 Angular는 여러 변수를 감시 할 수있는 단일 $watchGroup블록을 사용하여 감시 할 $watchGroup모든 변수를 포함 할 수있는 첫 번째 매개 변수로 배열을 사용합니다.

$scope.$watchGroup(['var1','var2'],function(newVals,oldVals){
   console.log("new value of var1 = " newVals[0]);
   console.log("new value of var2 = " newVals[1]);
   console.log("old value of var1 = " oldVals[0]);
   console.log("old value of var2 = " oldVals[1]);
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.