我尝试使用ng-model的输入标签类型文件:
<input type="file" ng-model="vm.uploadme" />
但是在选择了一个文件后,在控制器中,$scope.vm。Uploadme仍然没有定义。
我如何在我的控制器中获得所选文件?
我尝试使用ng-model的输入标签类型文件:
<input type="file" ng-model="vm.uploadme" />
但是在选择了一个文件后,在控制器中,$scope.vm。Uploadme仍然没有定义。
我如何在我的控制器中获得所选文件?
当前回答
这是一个稍微修改过的版本,允许你在作用域中指定属性的名称,就像你在ng-model, usage中所做的一样:
<myUpload key="file"></myUpload>
指令:
.directive('myUpload', function() {
return {
link: function postLink(scope, element, attrs) {
element.find("input").bind("change", function(changeEvent) {
var reader = new FileReader();
reader.onload = function(loadEvent) {
scope.$apply(function() {
scope[attrs.key] = loadEvent.target.result;
});
}
if (typeof(changeEvent.target.files[0]) === 'object') {
reader.readAsDataURL(changeEvent.target.files[0]);
};
});
},
controller: 'FileUploadCtrl',
template:
'<span class="btn btn-success fileinput-button">' +
'<i class="glyphicon glyphicon-plus"></i>' +
'<span>Replace Image</span>' +
'<input type="file" accept="image/*" name="files[]" multiple="">' +
'</span>',
restrict: 'E'
};
});
其他回答
我创建了一个指令并在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/
对于使用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);
});
});
}
}
}]);
我必须修改Endy的指令,这样我就可以得到最后修改,lastModifiedDate,名称,大小,类型和数据,以及能够得到一个文件数组。对于那些需要这些额外功能的人,这里就是。
更新: 我发现了一个错误,如果你选择了文件,然后再次选择但取消,这些文件永远不会像它出现时那样取消选择。所以我更新了代码来解决这个问题。
.directive("fileread", function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var readers = [] ,
files = changeEvent.target.files ,
datas = [] ;
if(!files.length){
scope.$apply(function () {
scope.fileread = [];
});
return;
}
for ( var i = 0 ; i < files.length ; i++ ) {
readers[ i ] = new FileReader();
readers[ i ].index = i;
readers[ i ].onload = function (loadEvent) {
var index = loadEvent.target.index;
datas.push({
lastModified: files[index].lastModified,
lastModifiedDate: files[index].lastModifiedDate,
name: files[index].name,
size: files[index].size,
type: files[index].type,
data: loadEvent.target.result
});
if ( datas.length === files.length ){
scope.$apply(function () {
scope.fileread = datas;
});
}
};
readers[ i ].readAsDataURL( files[i] );
}
});
}
}
});
或者你可以获取输入并设置onchange函数:
<input type="file" id="myFileInput" />
document.getElementById("myFileInput").onchange = function (event) {
console.log(event.target.files);
};
这是@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。