【问题标题】:How do I prevent AngularJS from unbinding a form input's value from its model when it's invalid?当表单输入的值无效时,如何防止 AngularJS 从其模型中解除绑定?
【发布时间】:2014-07-17 00:32:28
【问题描述】:

我正在使用 AngularJS 构建一个表单,我注意到一些我不理解的行为。

当我将ng-minlength=5 分配为输入属性时,AngularJS 会取消绑定该值,直到它比要求的长。

这对我来说很不方便,因为我想告诉用户他们使用user.lifestory.length 输入了多少内容。

为什么 AngularJS 会这样工作?如何防止 Angular 在值无效时解除绑定?

<label for="lifeStory">Life story:<input name='lifeStory' type="text" ng-model='user.lifeStory' ng-minlength='5' required></input></label>

这里有一个例子:http://jsfiddle.net/J67jm/3/

您可以通过填写生活故事字段来查看我所说的行为。

【问题讨论】:

  • 对电子邮件字段做同样的事情。保持模型为空,直到有效。不确定是什么解决方法

标签: javascript angularjs validation


【解决方案1】:

您可以使用{{myForm.lifeStory.$viewValue}} 获取 lifeStory 的当前 viewValue(尚未绑定到模型)。 这是解决您的问题的示例代码。

<span>Your life story needs to be at least 5 characters. You have entered {{myForm.lifeStory.$viewValue.length}} charaters.</span>

参考jsfiddle版本-http://jsfiddle.net/J67jm/9/

【讨论】:

  • 酷,我不知道$viewValue--很高兴看到他们有该属性可用。
  • @wulftone,使用 angularjs 有一个技巧。您始终可以使用 console.log($scope) 检查它们绑定的侦听器类型。
【解决方案2】:

当 minlength 无效时,Angular 似乎返回了 undefined 的值,但您可以制作自己的验证器指令:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
  $scope.user = {};
  $scope.user.name = "";
  $scope.user.lifeStory = "";
}

myApp.directive('myMinlength', function (){ 
  return {
    require: 'ngModel',
    link: function(scope, elem, attr, ngModel) {
      var minlength = parseInt(attr.myMinlength); // Just for Int's sake ;)

      ngModel.$parsers.unshift(function(value) {
        value = value || '';  // Prevent the value from being undefined
        var valid = value.length >= minlength;
        ngModel.$setValidity('myMinlength', valid);
        return value;  // return the value no matter what
      });
    }
  };
});

并像这样使用它:

<input name='lifeStory' type="text" ng-model='user.lifeStory' my-minlength='5' required></input>

这是更新后的jsfiddle

事实证明,ngRequired 具有相同的行为,并且可以以相同的方式修复。可能所有验证者都是这样?

我也想知道为什么 Angular 团队选择取消设置属性...

【讨论】:

  • 我认为这篇文章回答了为什么 - stackoverflow.com/questions/18676461/…
  • @hutingung 我明白他们的意思。我想指令很容易编写很好,所以我们可以根据需要创建自定义行为,对于像这个问题这样的情况。
  • 是的。但我认为最好不要为此目的创建指令。它可能会产生不一致的行为,即某些指令绑定无效值而某些不绑定。因此,我发布了使用表单中的 $viewValue 的答案。
【解决方案3】:

您还可以编写自定义验证器指令来为您恢复$viewValue,如下所示:

.directive('myParser', function () {
  return {
    restrict: 'A',
    require: 'ngModel',
    priority: 1, // force the postLink below to run after other directives
    link: function (scope, element, attrs, modelCtrl) {
      modelCtrl.$parsers.push(function (viewValue) {
        return (viewValue === undefined) ? modelCtrl.$viewValue : viewValue;
      });
    }
  }
});

并像这样使用它:

<input name="lifeStory" type="text" ng-model="user.lifeStory" ng-minlength="5" required my-parser></input>

示例插件: http://plnkr.co/edit/LbhF865FS8Zq5bQnpxnz?p=preview

【讨论】:

    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多