2013-07-22 14 views
48

Mam konfigurację zegarka przeciwko modelowi listy rozwijanej ui-select2 (z ui-bootstrap). Zegarek uruchamia się przy obciążeniu, ale nie na zmianach danych i nie wiem, dlaczego.

To nie jest zwykły problem polegający na tym, że $ nie stosuje zmiany modelu lub nie używa trzeciego parametru do porównywania równości (przynajmniej z mojego kodu).

Co należy zrobić, aby go uruchomić?

Here is a plunk demonstrating the issue.

+0

miałem $ nie oglądam strzelania ale okazuje się, że miałem ng-jeśli tworzyłem nowy zakres, więc musiałem umieścić ng-model = "$ parent.myModal", ponieważ faktycznie obserwowałem rodziców myModal .. –

Odpowiedz

32

Naprawiłem kilka rzeczy.

http://plnkr.co/edit/5Zaln7QT2gETVcGiMdoW?p=preview

JS

var myMod = angular.module("myApp",[]).controller("MainController", function($scope){ 
    $scope.myModel = {selectedId:null}; 
}).controller("DetailController",function($scope){ 
    $scope.items = [1,2,3,4]; 

    $scope.watchHitCount = 0; 
    $scope.$watch('myModel.selectedId', function(newVal, oldVal){ 
    console.log(newVal + " " + oldVal); 
    $scope.watchHitCount++; 
    },true); 
}); 

index.html

<body ng-app="myApp"> 
    <div ng-controller="MainController"> 
     <ng-include src="'detail.html'" ng-controller="DetailController"></ng-include> 
    </div> 
    </body> 

detail.html

<pre>watch hit: {{watchHitCount}}</pre> 
<pre>selected value: {{myModel.selectedId}}</pre> 
<select ng-model="myModel.selectedId" ui-select2=""> 
    <option></option> 
    <option ng-repeat="item in items" value="{{item}}">{{item}}</option> 
</select> 

został skarżą się na nie findi ng kontrolera, więc ustawiłem go tak, jak normalnie z nazwaną ng-app i modułem zadeklarowanym, że ma zdefiniowane kontrolery.

Dodałem również obiekt do przechowywania wartości w modelu. Złą praktyką jest używanie obiektu $ scope jako modelu, zamiast tego twój zakres powinien odnosić się do obiektu, który jest twoim modelem.

+5

Pogrubiłem część, która jest poprawką. Dzięki za pomoc. –

+0

Naprawiłem to również dla mnie! Dzięki :) –

+0

Więc to działało wcześniej dla mnie bez użycia obiektu ... W pewnym momencie to się zepsuło beze mnie dokonując bezpośrednich zmian w filtrach. Być może dodałem jakieś zmienne korzeniowe gdzie indziej i kilka obserwatorów w innych częściach składowych szablonu aplikacji. Czy istnieje wspólny powód, dla którego powinienem używać obiektów, a nie tylko zmiennych, jak w tym rozwiązaniu? – darkace

104

Spróbuj przejściu true jako 3 argument .$watch()

$rootScope.Scope documentation

$watch(watchExpression, listener, objectEquality) 

objectEquality (opcjonalny) - {logiczną =} - porównaj przedmiotu równości niż odniesienie .

+4

Uratowałeś mój dzień :) – jarandaf

+1

Pokonałem głowę o ścianę przez godzinę, próbując zrozumieć, dlaczego to było nie działa! Dziękuję Ci! –

+1

Angular to bestia, ale jednocześnie jest tak elegancka i tworzy doskonałe sceny, gdy już wiesz, co się dzieje. –

11

Istnieje prosty fix do tego, aby korzystać z zegarka złożonego obiektu, zamiast prostego zmiennej

na przykład (DON "T użytku)

$scope.selectedType=1;//default 
$scope.$watch(
      function() { 
       return $scope.selectedType; 
      }, 
      function (newValue, oldValue) { 
       if (!angular.equals(oldValue, newValue)) { 
        $scope.DoWork(); 
       } 
      }, 
      true); 

Ale Użyj poniżej

$scope.selecteditem={selectedType:1}; 
$scope.$watch(
      function() { 
       return $scope.selecteditem.selectedType; 
      }, 
      function (newValue, oldValue) { 
       if (!angular.equals(oldValue, newValue)) { 
        $scope.DoWork(); 
       } 
      }, 
      true); 

należy zauważyć, że "slectedTypes" w drugim przykładzie znajdującym się wewnątrz obiektu, a nie tylko zmienna zakresu, będzie działać nawet w starych wersjach Angular.

+0

Myślę, że moja odpowiedź może zadziałać, ale odpowiedź "@Casey Flynn" jest dokładniejsza i dokładniejsza. http://stackoverflow.com/a/17795221/471499 –

3

Jeśli używasz kontrolera jako podejście niektórych czytanie może sugerować składni takiego:

var myController = { 
    myValue: 1 
}; 
$scope.$watch('$ctrl.myValue', function() { 
    ... 
}, true); 

Zamiast po prostu zawinąć pola w funkcji takich jak to:

var myController = { 
    myValue: 1 
}; 
$scope.$watch(function() { 
    return myController.myValue; 
}, function() { 
    ... 
}, true); 
Powiązane problemy