【问题标题】:Modify radio button validity from an angular directive从角度指令修改单选按钮有效性
【发布时间】:2018-08-14 20:08:55
【问题描述】:

一旦用户开始填写输入,我就使用角度指令来更改表单输入的有效性:

angular.module('core').directive('serverError', function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, element, attrs, ctrl) {
      element.on('input', function() {
        scope.$apply(function() {
          ctrl.$setValidity('server', true);
        });
      });
      element.on('change', function() {
        scope.$apply(function() {
          ctrl.$setValidity('server', true);
        });
      });
    }
  };
});

我的表格是:

<input type="text" data-ng-model="request.lastname" name="lastname" required server-error/>
<div ng-show="form.lastname.$error.server">
    <span>Please fill this field</span>
</div>

<input type="radio" data-ng-model="request.civility" name="civility" value="M" required server-error> M.
<input type="radio" data-ng-model="request.civility" name="civility" value="F" required server-error> Mme
<input type="radio" data-ng-model="request.civility" name="civility" value="MISS" required server-error> Mlle
<div ng-show="form.civility.$error.server">
  <span>Please fill this field</span>
</div>

它适用于文本输入,但不适用于单选按钮。只有最后一个单选按钮按预期工作并使错误消失。

有解决这个问题的办法吗?

谢谢。

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    不幸的是,当一个带有 ng-model 的控件在表单中注册时,它会使用输入的名称将注册为表单的属性

    在您的情况下,您的所有 3 个单选按钮使用相同的名称(文明) =>第一个单选被第二个输入覆盖,第二个输入被第三个输入覆盖。 p>

    尝试为您的无线电输入使用不同的名称:

    <input type="radio" data-ng-model="request.civility" name="civility1" value="M" required server-error>M.
    <input type="radio" data-ng-model="request.civility" name="civility2" value="F" required server-error>Mme
    <input type="radio" data-ng-model="request.civility" name="civility3" value="MISS" required server-error>Mlle
    <div ng-show="form.civility1.$error.server && form.civility2.$error.server && form.civility3.$error.server">
        <span>Please fill this field</span>
    </div>
    

    DEMO

    【讨论】:

      【解决方案2】:

      由于每个无线电具有不同的名称会使无线电组的含义无效并使自动填写表格不可用,因此有一个更好的解决方法:

      基本上你必须使用 angulars jQuery-Lite 来获取 NgModelController。

       
      使用您的指令可能看起来像这样(我没有测试该代码):

      angular.module('core').directive('serverError', function() {
          return {
              restrict: 'A',
              require: '?ngModel',
              link: function(scope, element, attrs, ctrl) {
                  function updateValidity() {
                      const ngModelCtrl = element.controller('ngModel');
                      if (ngModelCtrl) {
                          ngModelCtrl.$setValidity('server', true);
                      }
                  }
      
                  element.on('input', updateValidity);
                  element.on('change', updateValidity);
              }
          };
      });
      

       
      在尝试评估来自服务器的验证响应并尝试从那里设置有效性后,我遇到了同样的问题。
      我没有使用指令。我之前尝试使用我的组件 FormController 设置有效性,例如formCtrl[inputName].$setValidity(...),但最终得到的行为与问题中描述的完全相同。
      所以我不得不把它改成这个(经过测试和工作):

      function updateValidity(control) {
          // `control` resembles `formCtrl[inputName]` as a parameter
          angular.element('input[name="' + control.$name + '"]').each((i, elem) => {
              const ngModelCtrl = angular.element(elem).data().$ngModelController;
              if (ngModelCtrl) {
                  ngModelCtrl.$setValidity('server', true);
              }
          });
      }
      

      【讨论】:

        猜你喜欢
        • 2023-04-10
        • 2014-03-30
        • 1970-01-01
        • 2017-11-29
        • 2016-11-09
        • 2023-01-29
        • 2018-09-23
        • 1970-01-01
        • 2014-09-20
        相关资源
        最近更新 更多