$ watch不会触发数据更改

µBi*_*Bio 57 angularjs jquery-select2 angular-ui-bootstrap

我有一个针对ui-select2下拉模型的手表设置(来自ui-bootstrap).手表会在负载时触发但不会在数据更改时触发,我无法弄清楚原因.

这不是通常的问题,即不应用模型更改或不使用第三个参数进行相等性比较(至少从我的代码中).

我需要做些什么来解雇它?

这是一个证明这个问题的插件.

Cas*_*ynn 122

尝试传递true作为第3个参数.$watch()

$rootScope.Scope 文件

$watch(watchExpression, listener, objectEquality)
Run Code Online (Sandbox Code Playgroud)

objectEquality(可选) - {boolean =} - 比较对象是否相等而不是参考.

  • 你救了我的一天:) (5认同)

sha*_*ain 35

我修了一些东西.

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);
});
Run Code Online (Sandbox Code Playgroud)

index.html

  <body ng-app="myApp">
    <div ng-controller="MainController">
      <ng-include src="'detail.html'" ng-controller="DetailController"></ng-include>
    </div>
  </body>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

它抱怨没有找到控制器所以我按照通常的方式设置了一个命名的ng-app和声明有控制器定义的模块.

我还添加了一个对象来保存模型中的值. 使用$ scope对象作为模型是不好的做法,而范围应该引用作为模型的对象.

  • 我加粗了修复部分.谢谢您的帮助. (5认同)

Tar*_*lah 12

有一个简单的解决方法,使用复杂对象的手表而不是简单的变量

例如(DON"T USE)

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

但请在下方使用

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

请注意,第二个示例中的"slectedTypes"位于对象内部,而不仅仅是范围变量.这甚至可以在旧的Angular版本中使用.


gar*_*ryp 6

如果您使用控制器 - 作为方法,一些阅读可能会建议这样的语法:

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

而只是将字段包装在这样的函数中:

var myController = {
    myValue: 1
};
$scope.$watch(function () {
    return myController.myValue;
}, function () {
    ...
}, true);
Run Code Online (Sandbox Code Playgroud)