여러 $ 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에서는 작동하지 않는 것 같습니다. 함수에 콘솔 로그를 넣으면 속성 이 정상적으로 작동하는 것을 보면서 개별 로 newValuesoldValuesas로 한 번만 실행되는 것을 볼 수 있습니다 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.