如何避免Angular JS中的$ watch服务?

时间:2016-09-21 04:59:33

标签: angularjs

我只想避免程序中的$ watch服务。有没有替代方案呢?

2 个答案:

答案 0 :(得分:3)

您可以通过以下策略避免使用手表:

  1. $ scope Communication
  2. ngModel $ parsers
  3. ngModel $ viewChangeListeners
  4. 的setInterval
  5. 过滤器
  6. 使用setInterval的示例:

    <div ng-app="MyApp">
      <div ng-controller="MyCtrl">
        <input ng-model="myModel.myProp">
        <br>
        <input ng-model="myModel.myProp2">
      </div>
    </div>
    
    <script>
      "use strict";
      angular.notifyMe = function(scope, expr, callbackFn) {
        var oldValue = scope.$eval(expr);
        setInterval(function() {
          var newValue = scope.$eval(expr);
          if (newValue !== oldValue) {
            setTimeout(function() {
              callbackFn.call(null, newValue, oldValue);
              oldValue = newValue;
            },0);
          }
        }, 100);
      };
      angular.module("MyApp", [])
      .controller("MyCtrl", function($scope, $filter) {
        $scope.myModel = {
          myProp: "Test Value",
          myProp2: "Test Value 2"
        };
        angular.notifyMe($scope, "myModel.myProp", function(newValue, oldValue) {
          console.log("int myProp value changed, new:" + newValue + ", old: " + oldValue);
        });
        angular.notifyMe($scope, "myModel.myProp2", function(newValue, oldValue) {
          console.log("int myProp2 value changed, new:" + newValue + ", old: " + oldValue);
        });
      });
    </script>
    

    更多详情here

    对于angular2,您可以使用OnChanges

    @Component({selector: 'my-cmp', template: `...`})
    class MyComponent implements OnChanges {
      @Input()
      prop: number;
      ngOnChanges(changes: SimpleChanges) {
        // changes.prop contains the old and the new value...
      }
    }
    

    你仍然可以在角度1.5上使用OnChanges

    这个钩子允许我们对组件的单向绑定的更改做出反应。 Angular 1.5中也引入了单向绑定,并且与Angular 2的单向数据流进行了更多对齐。假设我们使用单向绑定从外部世界配置myCmp的name属性:

    mod.component('myCmp', {
      template: '<h1>{{$ctrl.name}}</h1>',
      bindings: {
        name: '<'
      },
      controller: MyCmpController
    });
    

    我们现在可以将表达式绑定到组件的name属性,如下所示:

    <my-cmp name="someExpression"></my-cmp>
    

    假设我们希望在名称为“Pascal”时使用“Howdy”添加名称,否则只需使用“Hello”进行问候。我们可以使用$ onChanges()生命周期钩子来做到这一点。它被一个对象调用,该对象保存所有单向绑定与currentValue和previousValue的更改。

    function MyCmpController() {
      this.$onChanges = function (changesObj) {
        if (changesObj.name) {
          var prefix;
          (changesObj.name.currentValue === 'Pascal') ?
            prefix = 'Howdy ' : prefix = 'Hello ';
          this.name = prefix + this.name;
        }
      };
    }
    

答案 1 :(得分:0)

我为自己找到的最简单的策略是完全避免$scope。使用controller as将控制器绑定到范围,并直接与控制器交互;然后您可以使用简单的Javascript机制来检测更改。例如,ES5 getter / setters:

class FooController {
    get bar() {
        return this._bar;
    }

    set bar(value) {
        this._bar = value;
        console.log(this._bar);
    }
}

angular.module('Baz', []).controller('FooController', FooController);
<div ng-controller="FooController as ctrl">
    <input ng-model="ctrl.bar">
    ...