Angularjs “<;输入类型=";文件"/>;`(带指令演示)
我尝试在类型为file的输入标记上使用ng模型:Angularjs “<;输入类型=";文件"/>;`(带指令演示),angularjs,angularjs-ng-model,angularjs-fileupload,Angularjs,Angularjs Ng Model,Angularjs Fileupload,我尝试在类型为file的输入标记上使用ng模型: <input type="file" ng-model="vm.uploadme" /> 但是在选择了一个文件之后,在控制器中,$scope.vm.uploadme仍然是未定义的 如何在控制器中获取所选文件?我使用指令创建了一个解决方案: .directive("fileread", [function () { return { scope: { fileread: "="
<input type="file" ng-model="vm.uploadme" />
但是在选择了一个文件之后,在控制器中,$scope.vm.uploadme仍然是未定义的
如何在控制器中获取所选文件?我使用指令创建了一个解决方案:
.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
}
reader.readAsDataURL(changeEvent.target.files[0]);
});
}
}
}]);
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" fileread="vm.uploadme" />
这是@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"/>
该指令没有任何更改
现在,一切正常。我可以使用$scope.uploadme从控制器获取uploadme.src的值。我使用以下指令:
.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
}
reader.readAsDataURL(changeEvent.target.files[0]);
});
}
}
}]);
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.\u attachments\u uri.image)将填充您选择为数据uri的文件的内容(!)
请注意,此脚本不会上载任何内容。它将只使用数据uri(base64)编码的文件内容填充模型
请在此处查看工作演示:
我必须对多个输入执行相同的操作,所以我更新了@Endy Tjahjono方法。 它返回一个包含所有读取文件的数组
.directive("fileread", function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var readers = [] ,
files = changeEvent.target.files ,
datas = [] ;
for ( var i = 0 ; i < files.length ; i++ ) {
readers[ i ] = new FileReader();
readers[ i ].onload = function (loadEvent) {
datas.push( loadEvent.target.result );
if ( datas.length === files.length ){
scope.$apply(function () {
scope.fileread = datas;
});
}
}
readers[ i ].readAsDataURL( files[i] );
}
});
}
}
});
指令(“fileread”,函数(){
返回{
范围:{
文件读取:“=”
},
链接:功能(范围、元素、属性){
元素绑定(“更改”,函数(changeEvent){
变量读取器=[],
files=changevent.target.files,
数据=[];
对于(var i=0;i
这是一个稍加修改的版本,允许您在范围中指定属性的名称,就像使用ng model一样,用法:
<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'
};
});
.directive('myUpload',function(){
返回{
链接:函数postLink(范围、元素、属性){
元素。查找(“输入”)。绑定(“更改”,函数(changeEvent){
var reader=new FileReader();
reader.onload=函数(loadEvent){
作用域$apply(函数(){
scope[attrs.key]=loadEvent.target.result;
});
}
if(typeof(changevent.target.files[0])=='object'){
reader.readAsDataURL(changevent.target.files[0]);
};
});
},
控制器:“FileUploadCtrl”,
模板:
'' +
'' +
“替换图像”+
'' +
'',
限制:“E”
};
});
对于使用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);
});
});
}
}
}]);
我创建一个指令并在bower上注册 这个库将帮助您建模输入文件,不仅返回文件数据,还返回文件dataurl或base 64
{
"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="
}
如何使
与ng车型配合使用
指令的工作演示,适用于ng型号
核心ng model
指令不适用于开箱即用的
此自定义指令启用了ng模型
,并具有启用ng更改
、ng所需
、和ng表单
指令以使用
的额外好处
angular.module(“app”,[]);
angular.module(“app”)指令(“selectNgFiles”,function(){
返回{
要求:“ngModel”,
链接:功能后链接(范围、元素、属性、ngModel){
要素开启(“变更”,功能(e){
var files=elem[0]。文件;
ngModel.$setViewValue(文件);
})
}
}
});代码>
AngularJS输入`type=file`Demo
NameDateSizeType
{{file.name}
{{file.lastModified}日期:'MMMdd,yyyy'}
{{file.size}
{{file.type}
我必须修改Endy的指令,这样我就可以得到Last Modified、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] );
}
});
}
}
});
指令(“fileread”,函数(){
返回{
范围:{
文件读取:“=”
},
链接:功能(范围、元素、属性){
元素绑定(“更改”,函数(changeEvent){
变量读取器=[],
files=changevent.target.files,
数据=[];
如果(!files.length){
作用域:$apply(函数(){
scope.fileread=[];
});
返回;
}
对于(var i=0;i let fileToUpload = `${documentLocation}/${documentType}.pdf`;
let absoluteFilePath = path.resolve(__dirname, fileToUpload);
console.log(`Uploading document ${absoluteFilePath}`);
element.all(by.css("input[type='file']")).sendKeys(absoluteFilePath);
(function() {
'use strict';
/**
* @ngdoc input
* @name input[file]
*
* @description
* Adds very basic support for ngModel to `input[type=file]` fields.
*
* Requires AngularJS 1.4.x or later. Does not support Internet Explorer 9 - the browser's
* implementation of `HTMLInputElement` must have a `files` property for file inputs.
*
* @param {string} ngModel
* Assignable AngularJS expression to data-bind to. The data-bound object will be an instance
* of {@link https://developer.mozilla.org/en-US/docs/Web/API/FileList `FileList`}.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} ngChange
* AngularJS expression to be executed when input changes due to user interaction with the
* input element.
*/
angular
.module('yourModuleNameHere')
.decorator('inputDirective', myInputFileDecorator);
myInputFileDecorator.$inject = ['$delegate', '$browser', '$sniffer', '$filter', '$parse'];
function myInputFileDecorator($delegate, $browser, $sniffer, $filter, $parse) {
var inputDirective = $delegate[0],
preLink = inputDirective.link.pre;
inputDirective.link.pre = function (scope, element, attr, ctrl) {
if (ctrl[0]) {
if (angular.lowercase(attr.type) === 'file') {
fileInputType(
scope, element, attr, ctrl[0], $sniffer, $browser, $filter, $parse);
} else {
preLink.apply(this, arguments);
}
}
};
return $delegate;
}
function fileInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
element.on('change', function (ev) {
if (angular.isDefined(element[0].files)) {
ctrl.$setViewValue(element[0].files, ev && ev.type);
}
})
ctrl.$isEmpty = function (value) {
return !value || value.length === 0;
};
}
})();