Angular有没有办法在不使用$ watch的情况下对模型更改做出反应?

2oo*_*oom 5 javascript angularjs angularjs-directive angularjs-ng-change

我正在AngularJS中实现一个简单的微调控件,我想对用户输入和+/-按钮的更改做出反应.这是我的HTML:

<input type='button' ng-click="MyProperty = MyProperty - 1" value="-">
<input type='text' ng-model="MyProperty" ng-change="log('changed from ngChange')">
<input type='button' ng-click="MyProperty = MyProperty + 1" value="+">
Run Code Online (Sandbox Code Playgroud)

但是,这将仅跟踪"用户更改",ngChange因为根据文档,仅支持用户交互更新

所以现在我看着$scope.$watch弗雷德里克建议:

$scope.$watch('MyProperty', function() {
  $scope.log('changed from $watch');
});
Run Code Online (Sandbox Code Playgroud)

请参阅plunker演示

但这似乎并不正确.

  1. 首先它不是声明性的,你必须搜索代码MyTestProperty才能找到这个绑定.
  2. 如果你想要放在$scope.log一个单独的模型中,你必须注入$scope或在控制器中进行绑定.据我所知,这两种方式都不被认为是最好的实践.

有些人认为,$watch由于其他一些原因,这通常是件坏事.但是那里建议的解决方案(将直接调用logngClick)对我来说并没有太大的不同.基本上你必须手动跟踪所有的变化,如果有新的演员,你必须在那里复制你的逻辑.

所以问题是:有没有一种方法可以让你在没有$ watch的情况下自动跟踪模型更新?如果现在有这样的方式,那么实现自己的derective的想法有多糟糕?

Tom*_*mer 4

有几种方法可以做到这一点,但最优雅的方法是需要输入的 ngModel,然后使用它来查看/操作值。

这是更新的 Plunker

.directive('outputIt', function() {
    return {
      restrict: 'A',
      scope: {
        outputIt: '&'
      },
      require: '?ngModel',
      link: function(scope, element, attrs, ngModelCtrl) {
        ngModelCtrl.$parsers.push(function(val) {
          //console.log("the model was changed by input")
          scope.outputIt()(val);
        });
        ngModelCtrl.$formatters.push(function(viewValue) {
          //console.log("the model was changed from outside.");
          scope.outputIt()(viewValue);
          return viewValue;
        });
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)


要了解更多信息,这里有一篇非常酷的文章: Atricle

祝你好运!