如何使用angularjs中的输入[type=file]验证表单

时间:2022-11-24 10:10:04

HTML:

HTML:

<form name="form">
    <input type="file" ng-model="document" valid-file required>
    <input type="submit" value="{{ !form.$valid && 'invalid' || 'valid' }}">
</form>

Custom directive to listen for input[type=file] changes:

自定义指令侦听输入[type=file]更改:

myApp.directive('validFile',function(){
    return {
        require:'ngModel',
        link:function(scope,el,attrs,ngModel){

            //change event is fired when file is selected
            el.bind('change',function(){
                 scope.$apply(function(){
                     ngModel.$setViewValue(el.val());
                     ngModel.$render();
                 });
            });
        }
    };
});

When file is selected following error appears in console:

当选择文件时,控制台出现以下错误:

Error: InvalidStateError: DOM Exception 11 Error: An attempt was made to use an object that is not, or is no longer, usable.

错误:InvalidStateError: DOM Exception 11 Error:尝试使用不可用或不再可用的对象。

Try with plunkr: http://plnkr.co/edit/C5j5e0JyMjt9vUopLDHc?p=preview

试着与plunkr:http://plnkr.co/edit/C5j5e0JyMjt9vUopLDHc?p=preview

Without the directive the the state of the input file field wont be pushed to form.$valid. Any ideas why I get this error and how to fix this?

没有指令,输入文件字段的状态将不会被推到表单中。$valid。你知道我为什么会犯这个错误吗?

2 个解决方案

#1


29  

From the reference of NgModelController.$render()

从NgModelController的引用。$render()

Called when the view needs to be updated. It is expected that the user of the ng-model directive will implement this method.

当需要更新视图时调用。预期ng模型指令的用户将实现此方法。

You need to implement $render() to call it. You can do something like this

您需要实现$render()来调用它。你可以这样做

myApp.directive('validFile', function () {
    return {
        require: 'ngModel',
        link: function (scope, el, attrs, ngModel) {
            ngModel.$render = function () {
                ngModel.$setViewValue(el.val());
            };

            el.bind('change', function () {
                scope.$apply(function () {
                    ngModel.$render();
                });
            });
        }
    };
});

DEMO

演示

#2


4  

After updating to AngularJS 1.2.x the snippet looks not working properly anymore and the file input doesn't sticks with the selected file value, making the form unusable. Changing the directive back to your original one, and removing the ngModel.$render() it looks working like a charm:

更新到AngularJS 1.2之后。这个代码片段看起来不再正常工作了,而且文件输入没有坚持选择的文件值,使得表单无法使用。将指令修改回原始指令,并删除ngModel。

.directive('validFile', function () {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function (scope, el, attrs, ngModel) {
      el.bind('change', function () {
        scope.$apply(function () {
          ngModel.$setViewValue(el.val());
        });
      });
    }
  };

#1


29  

From the reference of NgModelController.$render()

从NgModelController的引用。$render()

Called when the view needs to be updated. It is expected that the user of the ng-model directive will implement this method.

当需要更新视图时调用。预期ng模型指令的用户将实现此方法。

You need to implement $render() to call it. You can do something like this

您需要实现$render()来调用它。你可以这样做

myApp.directive('validFile', function () {
    return {
        require: 'ngModel',
        link: function (scope, el, attrs, ngModel) {
            ngModel.$render = function () {
                ngModel.$setViewValue(el.val());
            };

            el.bind('change', function () {
                scope.$apply(function () {
                    ngModel.$render();
                });
            });
        }
    };
});

DEMO

演示

#2


4  

After updating to AngularJS 1.2.x the snippet looks not working properly anymore and the file input doesn't sticks with the selected file value, making the form unusable. Changing the directive back to your original one, and removing the ngModel.$render() it looks working like a charm:

更新到AngularJS 1.2之后。这个代码片段看起来不再正常工作了,而且文件输入没有坚持选择的文件值,使得表单无法使用。将指令修改回原始指令,并删除ngModel。

.directive('validFile', function () {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function (scope, el, attrs, ngModel) {
      el.bind('change', function () {
        scope.$apply(function () {
          ngModel.$setViewValue(el.val());
        });
      });
    }
  };