【问题标题】:Custom value on model when AngularJS $asyncValidator's promise rejectsAngularJS $asyncValidator 的承诺拒绝时模型上的自定义值
【发布时间】:2016-07-05 10:37:29
【问题描述】:

我正在通过指令在输入字段上运行自定义异步验证器:

angular.module("app", [])
.directive("accountDescriptionValidator", function ($q, $timeout) {
    function startValidation() {
      var startValidationDeferred = $q.defer();
      $timeout(function() { startValidationDeferred.resolve() }, 100);
      return startValidationDeferred.promise;
    }
    return {
        restrict: "A",
        require: "ngModel",
        scope: {
            parentModel: "="
        },
        link: function (scope, elm, attrs, ctrl) {
            ctrl.$asyncValidators["accountDescriptionValidator"] = function (modelValue, viewValue) {
                var accountDescriptionValidatorDefer = $q.defer();
                startValidation().then(function(accounts) {
                    if (viewValue == "aaa") {
                      accountDescriptionValidatorDefer.reject();
                    }
                    else {
                      accountDescriptionValidatorDefer.resolve();
                    }
                });
                return accountDescriptionValidatorDefer.promise;
            };
        }
    };
})

验证器做得很好;但是,当验证(正确地)失败时,绑定到输入字段的模型将从其父对象中完全删除。相反,我想要的是在其中保留最新的有效值。这可能吗?

编辑:plnkr 添加了here

EDIT2:现在问题代码与 plnkr 匹配

【问题讨论】:

  • 如果您可以使用 jsfiddle 之类的东西添加演示示例,将有助于更好地理解问题并尽早解决。
  • 您需要在指令中要求“ngModel”并访问 ngModelController 以修改 $modelValue。
  • @ShaunScovil 如您所见,ngModel 已经是必需的。但是,我将提供一个带有示例的 plunkr;你愿意详细说明你的答案吗?

标签: angularjs validation


【解决方案1】:

我看到您的问题有两种解决方案。

  • 使用另一个变量,它会保留最后一个正确的值。
  • 使用allowInvalid 选项。

plunker 上的实时示例。

// Code goes here

angular.module("app", [])
  .directive("accountDescriptionValidator", function($q, $timeout) {
    function startValidation() {
      var startValidationDeferred = $q.defer();
      $timeout(function() {
        startValidationDeferred.resolve()
      }, 100);
      return startValidationDeferred.promise;
    }
    return {
      restrict: "A",
      require: "ngModel",
      scope: {
        parentModel: "=",
        lastValidValue: "="
      },
      link: function(scope, elm, attrs, ctrl) {
        ctrl.$asyncValidators["accountDescriptionValidator"] = function(modelValue, viewValue) {
          var accountDescriptionValidatorDefer = $q.defer();
          startValidation().then(function(accounts) {
            if (viewValue == "aaa") {
              console.log('invalid');
              accountDescriptionValidatorDefer.reject();
            } else {
              scope.lastValidValue = modelValue;
              accountDescriptionValidatorDefer.resolve();
            }
          });
          return accountDescriptionValidatorDefer.promise;
        };
      }
    };
  })
  .controller("ctrl", function($scope) {
    $scope.obj = {};
  });
<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
</head>

<body ng-app="app">
  <div ng-controller="ctrl">
    <input type="text" ng-model="obj.description" account-description-validator last-valid-value="obj.lastDescription" />
    <br>Current value:{{ obj.description }}

    <br>Last valid value:{{ obj.lastDescription }}
    <br>By inserting "aaa" (without quotes) in the text field validation fails, and the model gets deleted! Instead, I'd like the model to be kept to the latest valid value. Validation has 100ms delay to simulate an async action.
    <br>
    <input type="text" ng-model="obj.description2" ng-model-options="{allowInvalid:true}" account-description-validator last-valid-value="obj.lastDescription2" />
    <br>Current value with allow invalid:{{ obj.description2 }}
  </div>
</body>

</html>

【讨论】:

  • 所以,我对您的建议进行了一些尝试。他们俩都没有真正做我想做的事,但是我感谢您的努力。到目前为止,我只使用了 allowInvalid 选项,无论如何我都会在模型中保留我的无效值。我会看看我是否可以通过其他方式来解决这个问题。
  • 请解释您为什么不喜欢带有lastValidValue的版本。
  • 因为我需要将该值保存到模型本身,而不是范围内的另一个值。这是因为我的表单是“实时编辑”表单,我没有“应用”按钮。我需要立即在模型中使用该值,因为如果用户离开表单,最后一个有效值应该已经在模型中。
  • 模型中的值,和INPUT中显示的值会不一样,如果没有通过验证?如果您没有通过验证,应该是什么行为? INPUT 中应该显示什么?
猜你喜欢
  • 2013-09-16
  • 2015-11-19
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 2017-09-04
相关资源
最近更新 更多