简体   繁体   English

angularjs指令监视未在对象函数属性上触发

[英]angularjs directive watch not fired on object function property

TL;DR: updating a property on a watched object does not seem to fire the watch when the property is a function . TL; DR:当该属性为function时,更新监视对象上的属性似乎不会触发监视。

Live example 现场例子

See this Plnkr exampl . 请参阅此Plnkr示例

The config object's properties can be changed by clicking the buttons in the example. 可以通过单击示例中的按钮来更改config对象的属性。 The objects are in sync (between directive and controller), and the $watch function in the directive (which simply ups a counter in this case) is called when a property is changed. 对象是同步的(在指令和控制器之间),并且在更改属性时,将调用指令中的$watch函数(在这种情况下,该函数只是增加一个计数器)。 Except when a function property is changed, which is what I do not understand. 除了当函数属性更改时,这是我不明白的。

Dead example 死的例子

View 视图

<main-dir config="configObject"></main-dir> 

Directive 指示

myApp.directive('mainDir', function () {

    return {
        restrict: 'E',
        scope: {config: '='},
        link: function (scope, el) {

            //(initialisation code)

            scope.$watch("config", function (config) {
                if (!config) return;
                // do stuff with config object
            }, true);

         }
     };
 });   

Controller 调节器

//init:
$scope.configObject = {
    propA: "value",
    propB: [1,2,3],
    propC: {key0: 3, key1: "value"},
    propD: function(x) {return x+1;}
}

//elsewhere:
$scope.configObject.propA = "other value"; //fires watch in directive
//or
$scope.configObject.propB = [3,2,1]; //fires watch in directive
//or
$scope.configObject.propB.push(5); //fires watch in directive
//or
$scope.configObject.propC = {key0: 1, key2: 34}; //fires watch in directive
//or
$scope.configObject.propC["key100"] = "newValue"; //fires watch in directive
//
// ... BUT ...
//
$scope.configObject.propD = function (x) {return x+2;} //does NOT fire watch in directive

So, in short: I can get the $watch to fire on changes to the object's properties. 简而言之:我可以使$watch在对象属性更改时触发。 But that doesn't seem to work if the property is a function. 但是,如果该属性是一个函数,那似乎不起作用。

Workaround: 解决方法:
When changing a property that is a function, I add a line changing a non-function property to fire the watch, like so: 当更改一个函数的属性时,我添加了一条更改非函数属性的行以触发手表,如下所示:

$scope.configObject.propD = function (x) {/*...new function def...*/};
$scope.configObject.xxx = Math.random(); //<-- causes watch to fire

Does anyone know why that is the case? 有人知道为什么会这样吗? Can I get the $watch to fire also on changes to function properties of the config object? 是否可以使$watch在config对象的功能属性更改时触发?

Thanks! 谢谢!

scope.$watch("config.propD") will watch reference to function instead of returning value scope.$watch("config.xxx") will watch return value from Math.random because you called function scope。$ watch(“ config.propD”)将监视对函数的引用,而不是返回值scope。$ watch(“ config.xxx”)将监视Math.random的返回值,因为您调用了function

Simplest way is to use $watchCollection documentation but it's not perfect one 最简单的方法是使用$ watchCollection 文档,但这不是完美的方法

  scope.$watchCollection('config',
    function(config) {
      scope.caught++;
    }
  );

Another way is to program collection of $watch'ers it's work slightly better: 另一种方法是对$ watch'ers的集合进行编程,它的工作会稍微好一些:

  angular.forEach(scope.config, function(value, key) {
    scope.$watch(function() {
      return scope.config[key];
    }, function(config) {
      scope.caught2++;
    }, true);
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM