【问题标题】:$watch not called when model property changes模型属性更改时未调用 $watch
【发布时间】:2015-09-27 00:27:25
【问题描述】:

我只是从 Angular 开始,并试图了解作用域 API 中的 $watch 函数。这是我的 JS fiddle 的链接:

JS Fiddle Watch demo Not working

var myApp = angular.module('myApp1', []);
angular.element(document).ready(function() {
         angular.bootstrap(document, ['myApp1']);    
});
function MyController($scope){
         var mc = this;
         mc.focus = {
            'name' :false,
            'email':false
           };

   $scope.$watch(mc.focus,function(oldVal,newVal){
     console.log(oldVal);
     console.log(newVal);
    },false);
    mc.allFilled = false;
    mc.setFocus = function(prop) {
       mc.focus[prop] = true;
    };
};    
myApp.controller("MyController",MyController);

我想做什么:

1) 为了简洁和演示,我有 4 个输入,在上面的链接中只包含一个。

2) 每个输入在焦点对象中都有对应的键,初始值为 false。

3) 每当使用 setFocus() 函数聚焦适当的输入元素时,我将在焦点对象中将属性值更改为 true

4) 一旦焦点对象中的所有属性都具有真实值,我想将 allFilled 属性更改为 true。

我想在这里做什么: 为了实现我想做的事情,我正在观察焦点对象,并且在侦听器中,我将检查所有属性是否都具有 true 值。如果是,我将更改 allFilled 属性/或做其他事情。

我知道也许我可以在setFocus() 本身中执行上述逻辑,但想尝试$watch
1) 是否可以使用$watch 执行此操作?
2) 为什么我的$watch 没有被调用?
3)在 Angular 中最好的方法是什么?

【问题讨论】:

  • 我的第三个问题的任何答案

标签: angularjs angularjs-scope watch


【解决方案1】:

好吧,问题是您没有将输入元素链接到任何范围对象。应该是的。

<input type="text" ng-focus="mc.setFocus('name')" ng-model="mc.focus" />
  {{mc.allFilled}}
  {{mc.focus}}
</div>

ng-focus 方法只在输入设置焦点时被调用,它没有说明与 i 链接的内容 正如@Chrillewoodz 指出的那样,它应该是一个字符串,但无论如何在输入上有一个 ng-model 是很好的。

【讨论】:

    【解决方案2】:

    手表需要一个字符串表达式,如下所示:

    $scope.$watch('mc.focus' ,function(oldVal,newVal){
        console.log(oldVal);
        console.log(newVal);
    },false);
    

    现在它将运行。

    您还需要在输入上设置ng-model 才能使这项工作正常进行。

    小提琴:http://jsfiddle.net/kn40tp2x/46/

    【讨论】:

    • @Chrillwoodz 不,它没有。您能否发布一个更新的 js fiddle 修改我提供的 js fiddle
    • @ShaileshVaishampayan 等一下,它对我有用,不知道更新前我做了什么改变。
    • 我正在我的手机上尝试。初始警报出现在我更新的新 jsfiddle 链接中。但是当我将注意力集中在输入上时,警报不会出现。我的新 jsfiddle 是否在您的浏览器上工作。
    • @ShaileshVaishampayan 不,因为这是错误的做法。我提供了你必须使用的小提琴。你需要在输入上有一个 ng-model,看看 fiddle 你就会看到。
    • 我明白了。只是霸主指出最后一个属性应该是真的。现在它起作用了。 jsfiddle.net/kn40tp2x/48
    【解决方案3】:

    代码中有两个错误。

    1. scope.$watch 文档说,第一个参数只能是 stringfunction。您不应该传递变量,除非它们的值是其中之一。

    2. 由于您正在观察对象属性的变化,因此 $watch 的第三个参数应设置为 true

    false - 通过引用相等比较对象,例如。旧值 === 新值。由于对象相同,所以没有发现变化。

    true - 查找对象中所有属性的更改。由于属性的值发生了变化,观察者将被触发。

    【讨论】:

    • 这是在 angular 中做这种事情的最佳方法吗?我正在做的是回答我的第三个问题:)?
    • 在我看来,很难说它是否是正确的方法。这当然是 Angular 1.x 的方式,但是框架的创建者认为这是错误的方式,并创建了 2.0 版本。在较大的程序中,观察者数量的增加会导致性能下降,因此有强烈的动机在可能的情况下使用事件,例如“焦点”。另一方面,简洁性可能会受到影响,并且示例中的代码不足以担心。
    • 示例中的代码不大,但实际示例中至少有 4 个字段。所以如果不是 $watch
    • 那么我应该听焦点事件吗?如果是,那么我将不得不创建一个指令,因为我们不应该在控制器中编写事件侦听器对吗?
    猜你喜欢
    • 2020-10-19
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2021-09-18
    相关资源
    最近更新 更多