【问题标题】:Prevent async unique validator to validate same value only when editing?防止异步唯一验证器仅在编辑时验证相同的值?
【发布时间】:2016-01-29 07:39:39
【问题描述】:

我有一个 AngularJS 表单,它有一个自定义验证器,用于与服务器后端检查输入值是否唯一。唯一验证由以下示例中的 mob-async-validate-unique 指令完成。

表格看起来有点像这样:

<form class="form-floating" novalidate="novalidate" ng-submit="saveItem(item)">
    <div class="form-group filled">
        <label class="control-label">Key</label>
        <input type="text" class="form-control" ng-model="item.Key" mob-async-validate-unique >
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-lg btn-primary">Save</button>
    </div>

</form>

我想使用相同的表单添加和编辑我放在$scope 上的模型。

一切都很好除了,因为唯一验证器会在编辑操作上触发,即使值与原始值相同,然后将唯一验证为 false因为该值已经存在。在以下两种情况下,验证器都会将该字段标记为无效:

  1. 更改字段值,然后将其编辑回原始值
  2. 提交表单而不做任何更改

实现这一目标的最佳方法是什么?我能想到的天真的方法是,我必须将原始值存储在 $scope.originalValue 变量上,然后在唯一的已验证元素上添加一个属性来命名该变量。在验证器中,我将从 $scope 中读取此值并将其与当前值进行比较,以使验证器在两个值相同时接受它。我将继续执行此操作。

我在多个地方以通用方式使用唯一验证器(是的,&lt;input&gt; 元素上使用了更多属性,为了简单和易读,我没有包含在代码示例中)并且需要验证器完全独立运行,理想情况下希望将控制器 $scope 排除在外,这样我就可以在任何地方/我想要的任何地方使用自定义异步验证器。

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-validation angularjs-forms


    【解决方案1】:

    根据您使用的 angularjs 版本,绝对不需要编写自定义异步验证器。 Angular 有一个内置的方法来做到这一点。检查https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

    当您按照文档中的描述使用 $asyncValidator 时,只有在所有其他验证都成功时,它才会针对您的 API 进行验证。

    ** 编辑 ** 关于编辑数据库中现有条目时的异步验证问题,我建议如下。

    var originalData = {};
    if(editMode) {
      originalData = data.from.your.API;
    } 
    $scope.formData = angular.copy(orignalData);
    
    // in your async validator
    if(value && value !== orginalData(key)) {
      //do async validation
    } else if(value == originalData(key)) {
      return true;  //field is valid
    }
    

    【讨论】:

    • 您提供的链接提供了一个示例,但不能以可重复使用的方式。制作验证器指令是(我知道)这样做的唯一方法。除此之外,总是需要解析/拒绝的代码。是的,我知道异步验证器仅在常规验证器(如requirednumber 等)验证后触发。请通读问题,当值相同时,我需要验证器在编辑模式下不拒绝。
    • 为您的案例添加了一个示例
    【解决方案2】:

    这是我解决问题的指令

    • 验证用户是否按键
    • 如果model valueinitialValue 相同。不会应用异步验证

      export default function ($http, API_URL, $q) {
        "ngInject";
        return {
          require: 'ngModel',
          restrict: 'A',
          scope: {
            asyncFieldValidator: '@',
            initialValue: '@'
          },
          link: ($scope, element, attrs, ngModel) => {
            const apiUrl = `${API_URL}${$scope.asyncFieldValidator}`;
      
            element.on('keyup', e => {
              ngModel.$asyncValidators.uniq = (modelValue, viewValue) => {
                const userInput = modelValue || viewValue;
                const checkInitial = $scope.initialValue === userInput;
                return !checkInitial
                  ? $http.get(apiUrl + userInput)
                    .then(res => res.status === 204 ? true : $q.reject())
                  : $q.resolve(`value is same`)
              }
            });
          }
        }
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 2018-04-16
      • 1970-01-01
      • 2021-07-20
      • 2021-11-29
      相关资源
      最近更新 更多