【问题标题】:Using scope.$watch to observe when a function executes使用 scope.$watch 观察函数何时执行
【发布时间】:2015-05-07 14:48:29
【问题描述】:

假设我有一个名为 my-directive 的自定义指令,它具有默认范围设置(scope: false,这意味着它共享包含该指令的(父)控制器的范围),并且我有一个函数 @987654323 @,附加到控制器的作用域。我想知道在自定义指令的链接函数中是否可以使用scope.$watch 来观察my_function 何时执行?

这里是一个说明代码:

<div ng-controller="MyCtrl">

    <my-directive></my-directive>

</div>

控制器:

app.controller('MyCtrl', function($scope) {

    $scope.my_function = function() {
    ...
    }

});

自定义指令:

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        [scope: false,]
        ...
        link: function(scope, element, attrs) {

            // can I scope.$watch my_function here to check when it executes?

        }
    }
});

更新:

这是我提出这个问题的原因: 当my_function(本质上是一个通过$http.get 的检索函数)执行时,它应该更新一个对象,比如my_data。如果我尝试scope.$watchmy_data,可能会出现my_function 执行并且my_data 没有变化的情况(例如当我在my_data 中编辑条目并决定无论如何取消更新时) ,因此我想在链接函数中执行的部分代码没有被执行。所以我想确保我在链接函数中的代码在my_function执行时执行,无论my_data是否有变化。

【问题讨论】:

  • 调用my_function的用例是什么?
  • @gustavohenke 检查我上面的更新。

标签: angularjs angularjs-directive


【解决方案1】:

这是我能想到的两种解决问题的方法。

1。使用计数器

在调用my_function 时,您始终可以增加一个计数器:

// This will reside in your controller
$scope.counter = 0;
$scope.my_function = function () {
  // do your logic
  $scope.counter++;
};

// This will reside in your directive
$scope.$watch( "counter", function () {
  // do something
});

2。只需观看my_data

假设my_function总是覆盖my_data 变量,您可以为$watch 使用默认的Angular 行为。您不必关心您的后端是否有消息给您,参考永远不会相同。

// in your controller
$scope.my_function = function () {
  $http.get(...).then(function ( response ) {
    $scope.my_data = response.data;
  });
};

// in your directive
$scope.$watch( "my_data", function () {
  // do something
});

显然,这是执行此操作的更简洁的方法,但如果由于以下原因之一不进行单元测试,您可能会遇到麻烦:

  • 您在my_data 周围添加任何可能与您的观察者冲突的逻辑;
  • 您想要缓存 HTTP 调用。

希望能帮到你!祝你好运。

【讨论】:

  • 谢谢。我没有尝试第一个,但第二个有效。这是否意味着scope.$watch 检查对象引用和实际值的变化?
  • 不,默认情况下只是对象引用。您可以通过传递 another true argument to $scope.$watch 来检查值是否相等。
【解决方案2】:

根据您要执行的操作,您可能根本不需要$watch

如果函数永远不会改变,你可以只做一个虚拟包装器。

link: function(scope, element, attrs) {

        var oldFunc = scope.my_function;
        scope.my_function = function(sameArgs){
            //method_was_called();
            if(oldFunc){oldFunc(sameArgs);}
        }

    }

然后,您可以在包装函数中执行任何您想要的逻辑,无论是在运行“超级”方法之前还是之后。

同时检查 Javascript: Extend a Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多