【问题标题】:$watch not firing on data change$watch 不会在数据更改时触发
【发布时间】:2013-07-21 15:08:21
【问题描述】:

我有一个针对 ui-select2 下拉列表模型的手表设置(来自 ui-bootstrap)。手表会在加载时触发,但不会在数据更改时触发,我不知道为什么。

不 $apply 模型更改或不使用第三个参数进行相等比较(至少从我的代码中)不是常见的问题。

我需要做什么才能让它着火?

Here is a plunk demonstrating the issue.

【问题讨论】:

  • 我有一个 $watch 没有触发,但事实证明我有一个 ng-if 正在创建一个新范围,所以我需要放置 ng-model="$parent.myModal",因为我是实际上是在看父母 myModal..

标签: angularjs jquery-select2 angular-ui-bootstrap


【解决方案1】:

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

$rootScope.Scope documentation

$watch(watchExpression, listener, objectEquality)

objectEquality(optional) – {boolean=} – 比较对象是否相等而不是参考。

【讨论】:

  • 我用头撞墙了一个小时,试图弄清楚为什么这不起作用!谢谢!
  • Angular 是一头野兽,但同时它又如此优雅,一旦你知道发生了什么,它就能做出完美的场景。
  • 你拯救了我的夜晚 :)。一直在努力修复几个小时。
  • 在那个丢失的参数上花了 3 个小时
  • 我所有团队的救生员;)
【解决方案2】:

我修复了一些东西。

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 对象用作模型是不好的做法,而您的作用域应该引用作为模型的对象。

【讨论】:

  • 我将修复的部分加粗。感谢您的帮助。
  • 这也为我修好了!谢谢:)
  • 所以这对我来说以前没有使用对象就可以工作......在某些时候,我没有直接更改过滤器就坏了。我可能在其他地方添加了一些 rootscope 变量,并在应用程序模板组件的其他地方添加了一些观察者。我应该使用对象而不是变量,就像在这个解决方案中一样,是否有一个常见的原因?
  • @shaunhusain 你能解释一下为什么变量不能工作任何对象工作
【解决方案3】:

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

例如(不要使用)

$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”位于对象内部,而不仅仅是范围变量。即使在旧的 Angular 版本中也可以使用。

【讨论】:

【解决方案4】:

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

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

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

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

【讨论】:

    【解决方案5】:

    唯一对我有用的东西:

      var ctrl = this;
    
      this.$onInit = function () {
        console.log("id " + ctrl.event.id);
      };
    

    来自https://docs.angularjs.org/guide/component#

    【讨论】:

      猜你喜欢
      • 2016-03-10
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 2014-07-20
      • 2020-04-10
      • 1970-01-01
      • 2013-03-29
      相关资源
      最近更新 更多