用于<input type =“ file” />验证的AngularJS指令

时间:2018-11-20 01:06:40

标签: javascript angularjs html5

鉴于AngularJS不支持此指令,我正在尝试使一个指令能够处理<input type="file">内部的<form>验证...一种检查文件是否有效的方法被选中,但是我在表单中也有一个<textarea>,所以当我选择一个文件时,表单的状态为$ valid = true,但是只要键入<textarea>,表单就会变成$ valid = false即使我尚未为<textarea>设置验证。为什么会这样?我该如何解决?这是一个简化的示例来说明问题:


我的app.js文件:

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

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});



app.directive('validFile', function () {
    return {
      restrict: "A",
      require: '^form',

      link: function (scope,elem,attrs, ctrl) {

        elem.bind("change", function(e) {
          console.log("change");
          scope.$apply(function(){
              ctrl.$valid=true;
              ctrl.$invalid=false;
          });
        });

      }
    };
  });

我的index.html文件:

    <!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write('<base href="' + document.location + '" />');</script>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
  <div ng-form="myForm" >
    <input ng-model="filename" valid-file required type="file"/>
    <button ng-disabled="myForm.$invalid" type="submit" class="btn btn-primary"><i class="icon-white icon-ok"></i>&nbsp;Ok</button>
    <div >
      <textarea name="observations" rows="3" cols="50" ng-model="observations"></textarea>
    </div> 
    <p> 
      Input is valid: {{myForm.$valid}} Input is invalid: {{myForm.$invalid}}
      <br>Selected file: {{filename}}
      <br>Area is valid: {{myForm.observations.$valid}} Area is invalid: {{myForm.observations.$invalid}}
    </p>
  </div>
</body>
</html>

我刚才说的有一个有用的说法:     http://plnkr.co/edit/k3KZpdX5q3pelWN21NVp?p=preview

1 个答案:

答案 0 :(得分:1)

一个快速的技巧就是像这样从ng-form中删除文本区域-

<div ng-form="myForm">
  <input id="userUpload" ng-model="filename" archivo-valido 
         name="userUpload" required type="file"
         accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
</div>
<button ng-disabled="myForm.$invalid" type="submit" class="btn btn-primary">
  <i class="icon-white icon-ok"></i>&nbsp;Ok
</button>

问题是Form开头是invalid,但是您只是在true上将值强制设为change。在textarea中写入内容后,Form会恢复为原始的false值。我不理解您指令中的代码-

  

错误

 scope.$apply(function(){
        if(true){ // will always evaluate to true. Why the else part then?
          ctrl.$valid=true;
          ctrl.$invalid=false;
        }else{
          ctrl.$valid=false;
        }
      });

一种更好的方法是像这样在您的每个ngModel上写Custom Validators-

app.directive('archivoValido', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
  ctrl.$validators.archivoValido = function(modelValue, viewValue) {
    if (ctrl.$isEmpty(modelValue)) {
      // consider empty models to be valid
      return true;
    }
     // your custom validation here
     ...
     // it is invalid
    return false;
  };
 }
};
});