在 angular 中上传多个文件
Upload multiple files in angular
我遇到这样一种情况,我有一个表单,其中一行有两个文本字段条目,我必须为该行上传一个文件,这种行可以是 '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>
如果你不关心低于 IE 9 的浏览器。那么你可以按照 this post 在你的 ng-submit 事件中构造一个 FormData 对象。这将创建一个 form/multipart,可能不是您想要的,但它确实有效。
这是文件值绑定指令示例..
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>
根据上面的 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 = {...
}
}
}
我遇到这样一种情况,我有一个表单,其中一行有两个文本字段条目,我必须为该行上传一个文件,这种行可以是 '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>
如果你不关心低于 IE 9 的浏览器。那么你可以按照 this post 在你的 ng-submit 事件中构造一个 FormData 对象。这将创建一个 form/multipart,可能不是您想要的,但它确实有效。
这是文件值绑定指令示例..
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>
根据上面的 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 = {...
}
}
}