AngularJS:当一个不同的元素发生变化时触发$ watch in指令

时间:2015-07-06 19:59:48

标签: javascript angularjs angularjs-directive watch

我在表单上有两个输入(field1field2)。 field1有一个$watch的指令,而field2在控制器中有一个$watch。添加或添加/删除值后,field1显示“此值有值”或“此字段没有值”。输入为原始信息时,该消息为空白。

更改field2会将field1的值更改为空白。我希望通过触发指令中的field1来为$watch显示“此字段没有价值”。

我的项目实际上有更复杂的计算和多个输入的检查,但这是我需要做的基本要点。

Plunker:http://plnkr.co/edit/XMdDt8M34VZJw1W0hkDt?p=preview

HTML:

<form name="myForm">
  <p>
    <label for="field1">Field 1</label>
    <input custom-validator name="field1" ng-model="item.field1" type="text" />
    <span>{{errorMessage}}</span>
  </p>
  <p>
    <label for="field2">Field 2</label>
    <input name="field2" ng-model="item.field2" type="text" />
  </p>
</form>

指令:

myApp.directive('customValidator', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attrs, ngModelCtrl) {
      scope.$watch(attrs.ngModel, function() {
        ngModelCtrl.$parsers.unshift(function(value) {
          if (value) {
            ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
            scope.$parent.errorMessage = 'This field has a value.'
          } else {
            ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
            scope.$parent.errorMessage = 'This field has no value.'
          }
        });
      });
    }
  }
});

控制器:

myApp.controller('FormController', function($scope) {
  $scope.item = {
    field1: '',
    field2: ''
  };

  $scope.$watch('item.field2', function(oldValue, newValue) {
    if (newValue) {
      $scope.item.field1 = '';
    }
  });
});

1 个答案:

答案 0 :(得分:0)

您需要向$formatters pipiline添加函数(因为您正在从控制器更改模型,而不是从视图 - 然后$parsers工作)并在模型变脏时运行它:

myApp.directive('customValidator', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attrs, ngModelCtrl) {

            ngModelCtrl.$parsers.unshift(function(value) {
                if (value) {
                    ngModelCtrl.$setValidity(ngModelCtrl.$name, false);
                    scope.errorMessage = 'This field has a value.'
                } else {
                    ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
                    scope.errorMessage = 'This field has no value.'
                }
            });

            ngModelCtrl.$formatters.unshift(function(value) {
                if (!value && ngModelCtrl.$dirty) {
                    ngModelCtrl.$setValidity(ngModelCtrl.$name, true);
                    scope.errorMessage = 'This field has no value.'
                }
            });
        }
    }
});

我还做了一些额外的更正。首先,删除$parent,因为您的指令与错误消息共享相同的范围。然后我更改了$watch函数中的参数顺序:它首先是newValue,第二个是oldValue

演示: http://plnkr.co/edit/VXpsrhvYliW9ICtFsdY6?p=preview