当它无效时,如何防止AngularJS从模型中解除表单输入值的绑定?

时间:2022-04-05 20:38:39

I'm building a form with AngularJS, and I noticed some behavior I don't understand.

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

When I assign ng-minlength=5 as an input attribute, AngularJS unbinds the value until it is longer than required.

当我将ng-minlength = 5指定为输入属性时,AngularJS会取消绑定该值,直到它超过所需值。

This is inconvenient for me because I'd like to tell the user how much content they've entered using user.lifestory.length.

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

Why does AngularJS work this way? How can prevent Angular from unbinding the value while it's invalid?

为什么AngularJS以这种方式工作?如何防止Angular在无效时解除绑定值?

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

An example of this is here: http://jsfiddle.net/J67jm/3/

这方面的一个例子是:http://jsfiddle.net/J67jm/3/

You can see the behavior I'm talking about by filling in the life story field.

你可以通过填写生活故事领域来看到我正在谈论的行为。

3 个解决方案

#1


4  

You can use {{myForm.lifeStory.$viewValue}} to get current viewValue of lifeStory (not bound to model yet). This is the sample code to solve your problem.

您可以使用{{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>

Refer to jsfiddle version - http://jsfiddle.net/J67jm/9/

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

#2


2  

Angular seems to return a value of undefined when the minlength is invalid, but you can make your own validator directive:

当minlength无效时,Angular似乎返回undefined值,但您可以创建自己的validator指令:

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

And use it like this:

并像这样使用它:

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

Here's the updated jsfiddle

这是更新的jsfiddle

It turns out that ngRequired has the same behavior, and can be fixed in the same way. It may be like this for all the validators?

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

I'd also like to know why the Angular team chose to unset the property...

我也想知道为什么Angular团队选择取消房产......

#3


1  

You could also write a custom validator directive to restore the $viewValue for you like this:

你也可以编写一个自定义验证器指令来为你恢复$ 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;
      });
    }
  }
});

and use it like this:

并像这样使用它:

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

Example plunker: http://plnkr.co/edit/LbhF865FS8Zq5bQnpxnz?p=preview

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

#1


4  

You can use {{myForm.lifeStory.$viewValue}} to get current viewValue of lifeStory (not bound to model yet). This is the sample code to solve your problem.

您可以使用{{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>

Refer to jsfiddle version - http://jsfiddle.net/J67jm/9/

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

#2


2  

Angular seems to return a value of undefined when the minlength is invalid, but you can make your own validator directive:

当minlength无效时,Angular似乎返回undefined值,但您可以创建自己的validator指令:

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

And use it like this:

并像这样使用它:

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

Here's the updated jsfiddle

这是更新的jsfiddle

It turns out that ngRequired has the same behavior, and can be fixed in the same way. It may be like this for all the validators?

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

I'd also like to know why the Angular team chose to unset the property...

我也想知道为什么Angular团队选择取消房产......

#3


1  

You could also write a custom validator directive to restore the $viewValue for you like this:

你也可以编写一个自定义验证器指令来为你恢复$ 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;
      });
    }
  }
});

and use it like this:

并像这样使用它:

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

Example plunker: http://plnkr.co/edit/LbhF865FS8Zq5bQnpxnz?p=preview

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