我尝试使用ng-model的输入标签类型文件:
<input type="file" ng-model="vm.uploadme" />
但是在选择了一个文件后,在控制器中,$scope.vm。Uploadme仍然没有定义。
我如何在我的控制器中获得所选文件?
我尝试使用ng-model的输入标签类型文件:
<input type="file" ng-model="vm.uploadme" />
但是在选择了一个文件后,在控制器中,$scope.vm。Uploadme仍然没有定义。
我如何在我的控制器中获得所选文件?
当前回答
如何使<input type="file">与ng-model一起工作
使用ng-model的指令的工作演示
核心ng-model指令不能使用<input type="file">开箱即用。
这个自定义指令启用了ng-model,并具有启用ng-change、ng-required和ng-form指令的额外好处,可以使用<input type="file">。
angular.module("app",[]); angular.module("app").directive("selectNgFiles", function() { return { require: "ngModel", link: function postLink(scope,elem,attrs,ngModel) { elem.on("change", function(e) { var files = elem[0].files; ngModel.$setViewValue(files); }) } } }); <script src="//unpkg.com/angular/angular.js"></script> <body ng-app="app"> <h1>AngularJS Input `type=file` Demo</h1> <input type="file" select-ng-files ng-model="fileArray" multiple> <code><table ng-show="fileArray.length"> <tr><td>Name</td><td>Date</td><td>Size</td><td>Type</td><tr> <tr ng-repeat="file in fileArray"> <td>{{file.name}}</td> <td>{{file.lastModified | date : 'MMMdd,yyyy'}}</td> <td>{{file.size}}</td> <td>{{file.type}}</td> </tr> </table></code> </body>
其他回答
我使用这个指令:
angular.module('appFilereader', []).directive('appFilereader', function($q) {
var slice = Array.prototype.slice;
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$render = function() {};
element.bind('change', function(e) {
var element = e.target;
$q.all(slice.call(element.files, 0).map(readFile))
.then(function(values) {
if (element.multiple) ngModel.$setViewValue(values);
else ngModel.$setViewValue(values.length ? values[0] : null);
});
function readFile(file) {
var deferred = $q.defer();
var reader = new FileReader();
reader.onload = function(e) {
deferred.resolve(e.target.result);
};
reader.onerror = function(e) {
deferred.reject(e);
};
reader.readAsDataURL(file);
return deferred.promise;
}
}); //change
} //link
}; //return
});
然后像这样调用它:
<input type="file" ng-model="editItem._attachments_uri.image" accept="image/*" app-filereader />
属性(editItem.editItem._attachments_uri.image)将使用您选择的文件内容填充为data-uri(!)。
请注意,这个脚本不会上传任何东西。它只会用数据uri (base64)编码的文件内容填充模型。
看看这里的工作演示: http://plnkr.co/CMiHKv2BEidM9SShm9Vv
我创建了一个指令并在bower上注册。
这个库将帮助您建模输入文件,不仅返回文件数据,而且还返回文件dataurl或base64。
{
"lastModified": 1438583972000,
"lastModifiedDate": "2015-08-03T06:39:32.000Z",
"name": "gitignore_global.txt",
"size": 236,
"type": "text/plain",
"data": "data:text/plain;base64,DQojaWdub3JlIHRodW1ibmFpbHMgY3JlYXRlZCBieSB3aW5kb3dz…xoDQoqLmJhaw0KKi5jYWNoZQ0KKi5pbGsNCioubG9nDQoqLmRsbA0KKi5saWINCiouc2JyDQo="
}
https://github.com/mistralworks/ng-file-model/
这是@endy-tjahjono解决方案的补充。
我最终无法从作用域获得uploadme的值。即使在HTML中的uploadme被指令明显地更新了,我仍然不能通过$scope.uploadme访问它的值。不过,我可以从作用域设置它的值。神秘的,对吧?
结果是,该指令创建了一个子作用域,并且子作用域有自己的uploadme。
解决方案是使用对象而不是原语来保存uploadme的值。
在控制器中我有:
$scope.uploadme = {};
$scope.uploadme.src = "";
在HTML中:
<input type="file" fileread="uploadme.src"/>
<input type="text" ng-model="uploadme.src"/>
指令没有变化。
现在,一切都像预期的那样。我可以获取uploadme的值。SRC从我的控制器使用$scope.uploadme。
如何使<input type="file">与ng-model一起工作
使用ng-model的指令的工作演示
核心ng-model指令不能使用<input type="file">开箱即用。
这个自定义指令启用了ng-model,并具有启用ng-change、ng-required和ng-form指令的额外好处,可以使用<input type="file">。
angular.module("app",[]); angular.module("app").directive("selectNgFiles", function() { return { require: "ngModel", link: function postLink(scope,elem,attrs,ngModel) { elem.on("change", function(e) { var files = elem[0].files; ngModel.$setViewValue(files); }) } } }); <script src="//unpkg.com/angular/angular.js"></script> <body ng-app="app"> <h1>AngularJS Input `type=file` Demo</h1> <input type="file" select-ng-files ng-model="fileArray" multiple> <code><table ng-show="fileArray.length"> <tr><td>Name</td><td>Date</td><td>Size</td><td>Type</td><tr> <tr ng-repeat="file in fileArray"> <td>{{file.name}}</td> <td>{{file.lastModified | date : 'MMMdd,yyyy'}}</td> <td>{{file.size}}</td> <td>{{file.type}}</td> </tr> </table></code> </body>
对于使用lodash或下划线输入的多个文件:
.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
return _.map(changeEvent.target.files, function(file){
scope.fileread = [];
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread.push(loadEvent.target.result);
});
}
reader.readAsDataURL(file);
});
});
}
}
}]);