【问题标题】:AngularJS directive for <input type="file"> validation<input type="file"> 验证的 AngularJS 指令
【发布时间】:2018-11-20 01:06:40
【问题描述】:

鉴于 AngularJS 不支持此功能,我正在尝试制作一个能够在 &lt;form&gt; 内处理 &lt;input type="file"&gt; 验证的指令......它可以检查是否选择了文件,但是我在表单中也有一个&lt;textarea&gt;,所以当我选择一个文件时,表单的状态为 $valid=true,但只需输入&lt;textarea&gt;,即使我没有设置验证&lt;textarea&gt;。为什么会这样?我该如何解决?下面是一个简化的例子来说明这个问题:


我的 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>

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

【问题讨论】:

    标签: javascript angularjs html


    【解决方案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,但您只需在change 上将值强制为true。一旦你在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;
      };
     }
    };
    });
    

    【讨论】:

    • 嗨,我刚刚修改了代码,所以你说你“不明白”的那段代码更清晰(它的目的是让输入始终有效,所以我们可以看到它是如何使 textarea程序失败)我也更改了html代码,所以我可以看到form.textArea.$validform.textArea.$invalid但没有像你说的那样显示,textArea总是$valid=true和$invalid=false。
    • @gerard 感谢您使答案更清晰。关于您的疑问,更改的不是form.textArea.$valid,而是form.$valid 在更改textArea 时恢复到原来的false 值。
    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多