【问题标题】:AngularJS : Trigger $watch in directive when a different element changesAngularJS:当不同的元素发生变化时,在指令中触发 $watch
【发布时间】:2015-09-24 02:46:36
【问题描述】:

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

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

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

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 = '';
    }
  });
});

【问题讨论】:

    标签: javascript angularjs angularjs-directive watch


    【解决方案1】:

    您需要向$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

    【讨论】:

    • 你将如何改变它以使 $parsers 和 $formatters 使用相同的验证函数?我想避免重复代码。
    • 谢谢。接受答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    相关资源
    最近更新 更多