【问题标题】:Toggle or disable/re-enable an AngularJS watch切换或禁用/重新启用 AngularJS 手表
【发布时间】:2015-10-30 04:41:58
【问题描述】:

我需要能够在执行特定任务时忽略特定的手表。这是场景。


我在用于计算“总计”字段的字段上有几个观察者。

所有这些字段都可以手动修改,这将触发计算“总计”字段的手表。

字段也可以从保存状态加载,这也会触发计算“totals”字段的手表。

“总计”字段也可以手动覆盖、保存和加载。

当手动覆盖的“总计”字段与其他字段一起加载时会出现此问题。重新计算“总数”的手表被触发,并覆盖手动覆盖的“总数”。

我需要能够在负载发生时忽略手表。有什么办法吗?

我知道可以使用创建手表时传回的取消注册功能禁用观察者,但是当您重新创建观察者时,它仍然知道它正在观察的数据已更改。

注意:这是对围绕问题的业务逻辑的过于简化的描述。无法禁用手表将需要大量工作。

这是一个显示问题的小提琴:jsfiddle.net/vGWZy/1/

【问题讨论】:

  • 您有什么理由特别使用手表吗?从它的声音来看,$scope 应该能够处理所有这些。也许创建一个小提琴会有所帮助。
  • 这是一个非常大的业务逻辑,数据变化的方式有很多种。不使用手表将是一场噩梦。我会看看我是否可以拼凑一个简单的小提琴来展示这个问题。希望有人能对这是否至少是可能的有一个明确的答案。
  • 我认为如果可能的话,一个简单的例子在这里会很有帮助。
  • 添加了一个小提琴来演示这个问题。 jsfiddle.net/vGWZy/1/
  • 对不起,我最初发布了错误的小提琴链接。它现在已更新。

标签: angularjs toggle listener watch


【解决方案1】:

您可以将watcher的回调和disabler存储在特殊服务中,并使用service方法的绑定和解除绑定

以您的代码为例 http://jsfiddle.net/snicksnk/66osj8zm/

//Service for working with watcher's binding
var watchService = {
    watchers: {},
    create: function(name, callback){

        watchService.watchers[name] = 
        {
            'callback': callback,
            'disableCallback': null
        };
    },
    enable: function($scope, name){
        if (typeof watchService.watchers[name]['callback'] !== 'function'){
            return;
        }
        watchService.disable(name);
        var watcher = watchService.watchers[name]['callback'];
        watchService.watchers[name]['disableCallback'] = $scope.$watch(name, watcher, true);


    },
    disable: function(name){
        if (typeof watchService.watchers[name]['disableCallback'] !== 'function'){
            return;
        }
        watchService.watchers[name]['disableCallback']();
    }
};

//Creating of watcher's callbacks, instead of using $scope.$watch directly
watchService.create('item.value1',  function() {
    $scope.item.total = $scope.item.value1 * $scope.item.value2;
});


watchService.create('item.value2',  function() {
    $scope.item.total = $scope.item.value1 * $scope.item.value2;
});



//Wathcers enabler
$scope.enableWatchers = function(){
    watchService.enable($scope, 'item.value1');
    watchService.enable($scope, 'item.value2');
};

//Wathcers disable
$scope.disableWatchers = function(){
    watchService.disable('item.value1');
    watchService.disable('item.value2');
};

【讨论】:

    【解决方案2】:

    当您调用 $watch() 方法来创建绑定时,Angular JS 会返回一个“取消注册”函数。然后可以使用此函数取消绑定您的 $watch() 侦听器 - 您所要做的就是调用此返回的函数,您的 $watch() 侦听器将被删除。

    var leaveWatcher = function() {
      $scope.$watch('selectedStatus', function(newValue, oldValue) {
        if (newValue[0] === "*") {
          .......
          leaveWatcher(); //Disable
        }
      });
    };
    
    leaveWatcher(); //Enable

    http://www.bennadel.com/blog/2480-unbinding-watch-listeners-in-angularjs.htm

    【讨论】:

      【解决方案3】:

      您可能想尝试使用ng-change 来获得所需的结果。

      这是一个example,它使用ng-change调用一个函数来计算总值。

      查看

      <html ng-app>
      
        <head>
          <script data-require="angular.js@1.2.9" data-semver="1.2.9" src="http://code.angularjs.org/1.2.9/angular.js"></script>
          <link rel="stylesheet" href="style.css" />
          <script src="script.js"></script>
        </head>
      
        <body ng-controller="ExampleCtrl">
           <h1>Hello Plunker!</h1>
      
          <label>Value 1:</label><input type="number" ng-model="value1" ng-change="updateTotal()"><br />
          <label>Value 2:</label><input type="number" ng-model="value2" ng-change="updateTotal()"><br />
          <label>Value 3:</label><input type="number" ng-model="value3" ng-change="updateTotal()"><br />
      
          <label>Total:</label><input type="number" ng-model="total" placeholder="Total"><br />
        </body>
      
      </html>
      

      控制器

      function ExampleCtrl($scope){
          $scope.value1 = 0;
          $scope.value2 = 0;
          $scope.value3 = 0;
          $scope.total = 0
      
          $scope.updateTotal = function(){
             $scope.total = $scope.value1 + $scope.value2 + $scope.value3;
         };
      }
      

      这只是一个简单的例子,但也许您可以根据自己的需要对其进行调整。

      【讨论】:

      • 我不相信 ng-change 会起作用,因为值可以在没有任何用户输入的情况下改变。我相信只有在用户进行更新时才会激活 ng-change?
      • 在什么情况下会改变?
      • 可以加载模板以预填充字段,可以加载保存的状态,用户可以在框中输入内容,在一个框中输入可以触发另一个框的更新。
      猜你喜欢
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      相关资源
      最近更新 更多