2013-07-22 122 views
48

我有一個針對ui-select2下拉菜單(來自ui-bootstrap)的手錶設置。該手錶在加載時觸發,但不是數據更改,我無法弄清楚原因。

這不是通常的問題,不是$ apply'ing模型的變化或不使用第三個參數進行等式比較(至少從我的代碼)。

我需要做些什麼才能讓它着火?

Here is a plunk demonstrating the issue.

+0

我有一個$ watch not firing,但事實證明我有一個ng - 如果這是創建一個新的範圍,所以我需要把ng-model =「$ parent.myModal」,因爲我實際上正在看父母myModal .. –

回答

32

我修復了一些東西。

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> 

有人抱怨不遇見所以我按照我通常用名爲ng-app的方式設置控制器,並聲明一個模塊已定義控制器。

我還添加了一個對象來保存模型中的值。使用$ scope對象作爲你的模型是一個不好的做法,相反你的作用域應該引用一個你的模型的對象。

+5

我粗體顯示了修復的部分。謝謝您的幫助。 –

+0

這也爲我修好了!謝謝:) –

+0

所以這工作以前對我沒有使用一個對象...在某些時候,這打破了沒有我直接改變過濾器。我可能在應用程序模板組件中的其他地方添加了一些rootcope變量,並在其他地方添加了一些觀察者。是否有一個共同原因,爲什麼我應該使用對象而不僅僅是變量,如在此解決方案中一樣? – darkace

104

嘗試傳遞true作爲第三參數.$watch()

$rootScope.Scope documentation

$watch(watchExpression, listener, objectEquality) 

objectEquality(可選) - {布爾=} - 對平等而不是參考比較對象。

+4

您保存了我的一天:) – jarandaf

+1

我打了一個小時的頭撞牆,試圖找出爲什麼這是不工作!謝謝! –

+1

Angular是一個野獸,但同時它的優雅和完美的場景,一旦你知道發生了什麼事情。 –

11

存在用於一個簡單的解決,使用手錶具有複雜對象,而不是簡單的變量

例如(DON「T USE)

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

但是使用下面

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

請注意,第二個示例中的「slectedTypes」位於對象內部,而不僅僅是scope變量,即使在舊的Angular版本中也是如此。

+0

我認爲我的答案可以奏效,但「@Casey Flynn」的回答更加準確和精確。 http://stackoverflow.com/a/17795221/471499 –

3

如果你使用的控制器爲逼近一些閱讀可能會建議這樣的語法:

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

相反只是包裝在這樣的功能領域:

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