以角度上传多个文件

Posted

技术标签:

【中文标题】以角度上传多个文件【英文标题】:Upload multiple files in angular 【发布时间】:2015-10-02 23:09:28 【问题描述】:

我有一种情况,我有一个表格,其中有一行,我有两个文本字段条目,我必须为该行上传一个文件,这种行可以是“N”然后有一个可以为整个表单输入的主文件,而这些是表单的一部分,我必须在单击保存按钮时立即提交所有这些文件。

我有点被 ng-upload 卡住了,它需要一个 api 调用,而且我真的不能对这个表单进行多个 api 调用。 示例 html 代码如下:

<!DOCTYPE html>
<html>

<head>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>

  <form editable-form name="xyzForm" ng-submit="create(model)">
    <label>Tags: </label><input class="col-xs-12 col-md-12" ng-model="model.tags" type="text" name="Tags">
    <label>Notes: </label> <input class="col-xs-12 col-md-11" ng-model="model.notes" type="text" name="notes">
    <table class=" col-xs-3 col-md-11 table" border="1px solid red;">
      <thead>
        <tr>
          <th>Product</th>
          <th>Manufacturer</th>
          <th>Location</th>
          <th>Specification</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="itemRow in item.singleItem">
          <td><input type="text" class="xdTextBox" name="itemRow.name" ng-model="model.itemRow[$index].name" /></td>
          <td><input type="text" class="xdTextBox" name="itemRow.manufacturer" ng-model="model.itemRow[$index].manufacturer" /></td>
          <td><input type="text" class="xdTextBox" name="itemRow.location" ng-model="model.itemRow[$index].location" /></td>
          <td><i class="pull-left glyphicon glyphicon-upload"><input type="file" name="itemRow.doc" ng-model="model.itemRow[$index].doc" multiple=false></i></td>
          <td><i class="pull-left glyphicon glyphicon-remove"></i></td>
        </tr>

      </tbody>
      </span>
    </table>

    <label>Product Spec: </label><input type="file" ng-model="prefabdoc" multiple="true" ngf-maxsize="15000000" />
  </form>

</body>

</html>

【问题讨论】:

不能使用https://github.com/danialfarid/ng-file-upload 吗? 我在我的代码中已经使用了相同的东西,但是对如何同时为多个文件实现这个以及在表单中不同位置的不同文件集实现这一点感到困惑 这也是youtube上的一个很好的资源:@​​987654321@ @Bran Stark - 我正在努力实现您在上面的问题陈述中提到的内容。我是 Angular Js 的新手,我发现下面接受的答案有点接近,但仍然不清楚我该如何实现对于您上面提到的问题陈述。您能否分享您实现的代码,这将非常有帮助..谢谢。 接受的答案对你有用吗@BranStark? 【参考方案1】:

这是文件值绑定指令示例..

http://plnkr.co/edit/B13t84j5IPzINMh1F862?p=preview

js代码为:

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

app.controller('MainCtrl', function($scope) 
  $scope.name = 'World';
  $scope.files = []; 
  $scope.upload=function()
    alert($scope.files.length+" files selected ... Write your Upload Code"); 

  ;
);


app.directive('ngFileModel', ['$parse', function ($parse) 
    return 
        restrict: 'A',
        link: function (scope, element, attrs) 
            var model = $parse(attrs.ngFileModel);
            var isMultiple = attrs.multiple;
            var modelSetter = model.assign;
            element.bind('change', function () 
                var values = [];
                angular.forEach(element[0].files, function (item) 
                    var value = 
                       // File Name 
                        name: item.name,
                        //File Size 
                        size: item.size,
                        //File URL to view 
                        url: URL.createObjectURL(item),
                        // File Input Value 
                        _file: item
                    ;
                    values.push(value);
                );
                scope.$apply(function () 
                    if (isMultiple) 
                        modelSetter(scope, values);
                     else 
                        modelSetter(scope, values[0]);
                    
                );
            );
        
    ;
]);

HTML代码是:

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link href="style.css" rel="stylesheet" />
    <script data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js" 
        data-require="angular.js@1.4.x"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello name!</p>
    <input type="file" ng-file-model="files" multiple />
    <button type="button" ng-click="upload()">Upload</button>

    <p ng-repeat="file in files">
      file.name
    </p>
  </body>

</html>

【讨论】:

如何限制可上传文件的数量,比如一次最多需要上传5个文件 你可以在 $scope.upload 方法 $scope.file.length>5 上做到这一点,别忘了这段代码只是解释了如何绑定 angularjs 和 fileinput ...阅读文件上传developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…并替换为警报代码..我希望这会有所帮助.. 那么,现在这些文件可以通过“values”数组在控制器中使用,对吧?如values[i]。为什么要在上传功能中使用“files”变量访问它? php中输出类似这样的东西[additionals] =&gt; [object File],[object File] 该指令的对象支持上传前显示文件的浏览器基础视图,名称大小验证等,您可以按值访问原始文件。_file【参考方案2】:

如果您不关心低于 IE 9 的浏览器。那么您可以关注 this post 并在您的 ng-submit 事件中构造一个 FormData 对象。这将创建一个表单/多部分,可能不是您想要的,但它可以解决问题。

【讨论】:

感谢您指出这篇文章。我在这里有两种不同类型的表单文件,每个产品项一个或多个,整个产品本身一个或多个文件。但我喜欢这里实现多表单的方式。 在您发出 post 请求之前,应该可以将两种类型的表单文件合并为一个 FormData 对象。不过自己没试过:)! 是的,听起来不错,我现在正在尝试,让我看看是否可以将所有文件数据放到服务器端。 我有点卡住了,我想用另一种方法发布 $http ,而我试图从上面的链接将文件数据填充到 fd 中,并且文件数据不显示。即使在附加文件之后,FormData 也是空的 我正在尝试以不同的方法执行 $http.post,我想在此处返回这个 FormData,但是这个是空的?我做错了什么,filedatais not going into FormData 这里是代码pastebin.com/DM4LNWkF【参考方案3】:

来自saltuk's 上面的答案有一个小的变化,代码可以工作

    var modelSetter = model.assign;
        element.bind('change', function () 
            var values = [];
            angular.forEach(element[0].files, function (item) 
                var value = ...
                
            
        

数组 var 应该在上面的 forEach 函数之前定义

    var modelSetter = model.assign;
    element.bind('change', function () 
        var values = [];
        angular.forEach(element[0].files, function (item) 
            var value = ...
            
        
    

【讨论】:

以上是关于以角度上传多个文件的主要内容,如果未能解决你的问题,请参考以下文章

以角度 8 上传 zip 文件

从春季启动以角度4发布上传文件?

以角度形式为文件上传设置自定义验证未按预期工作

如何以角度2上传base64文件

以角度 5 上传前的图像预览

可以导出多个kendo网格以实现角度优势