ng-model para “ (com diretiva DEMO)

Eu tentei usar o ng-model na tag de input com o arquivo type:

 

Mas depois de selecionar um arquivo, no controller, $ scope.vm.uploadme ainda está indefinido.

Como faço para obter o arquivo selecionado no meu controlador?

Eu criei uma solução alternativa com diretiva:

 .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]); }); } } }]); 

E a tag de input se torna:

  

Ou se apenas a definição de arquivo for necessária:

 .directive("fileread", [function () { return { scope: { fileread: "=" }, link: function (scope, element, attributes) { element.bind("change", function (changeEvent) { scope.$apply(function () { scope.fileread = changeEvent.target.files[0]; // or all selected files: // scope.fileread = changeEvent.target.files; }); }); } } }]); 

Eu uso esta diretiva:

 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 }); 

e invocá-lo assim:

  

A propriedade (editItem.editItem._attachments_uri.image) será preenchida com o conteúdo do arquivo selecionado como um data-uri (!).

Por favor, note que este script não fará upload de nada. Ele só preencherá seu modelo com o conteúdo do seu arquivo codificado ad um data-uri (base64).

Confira uma demonstração de trabalho aqui: http://plnkr.co/CMiHKv2BEidM9SShm9Vv

Este é um adendo à solução do @ endy-tjahjono.

Acabei não conseguindo obter o valor de uploadme do escopo. Embora o uploadme no HTML tenha sido visivelmente atualizado pela diretiva, ainda não consegui acessar seu valor por $ scope.uploadme. Eu consegui definir seu valor no escopo, no entanto. Misterioso, certo ..?

Como se viu, um escopo filho foi criado pela diretiva e o escopo filho tinha seu próprio uploadme .

A solução foi usar um object em vez de um primitivo para manter o valor de uploadme .

No controlador eu tenho:

 $scope.uploadme = {}; $scope.uploadme.src = ""; 

e no HTML:

    

Não há alterações na diretiva.

Agora, tudo funciona como esperado. Eu posso pegar o valor de uploadme.src do meu controlador usando $ scope.uploadme.

Demonstração de trabalho da diretiva que funciona com o ng-model

Como habilitar para trabalhar com ng-model

A diretiva ng-model não funciona com fora da checkbox.

Essa diretiva personalizada habilita ng-model e tem o benefício adicional de ativar as diretivas ng-change , ng-required e ng-form para trabalhar com .

 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); }) } } }); 
   

AngularJS Input `type=file` Demo

NameDateSizeType
{{file.name}} {{file.lastModified | date : 'MMMdd,yyyy'}} {{file.size}} {{file.type}}

Oi pessoal eu crio uma diretiva e me cadastro no bower.

essa lib irá ajudá-lo a modelar o arquivo de input, não apenas retornar os dados do arquivo, mas também o arquivo dataurl ou 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=" } 

https://github.com/mistralworks/ng-file-model/

Espero que te ajude

Esta é uma versão ligeiramente modificada que permite especificar o nome do atributo no escopo, assim como você faria com o uso do modelo ng:

   

Directiva:

 .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: '' + '' + 'Replace Image' + '' + '', restrict: 'E' }; }); 

Para input de vários arquivos usando lodash ou sublinhado:

 .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); }); }); } } }]); 

Eu tive que fazer o mesmo em várias inputs, então atualizei o método @Endy Tjahjono. Ele retorna uma matriz contendo todos os arquivos lidos.

  .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] ); } }); } } }); 
 function filesModelDirective(){ return { controller: function($parse, $element, $attrs, $scope){ var exp = $parse($attrs.filesModel); $element.on('change', function(){ exp.assign($scope, this.files[0]); $scope.$apply(); }); } }; } app.directive('filesModel', filesModelDirective); 

Eu tive que modificar a diretiva da Endy para que eu possa obter Last Modified, lastModifiedDate, nome, tamanho, tipo e dados, bem como ser capaz de obter uma matriz de arquivos. Para aqueles de vocês que precisavam desses resources extras, aqui vai você.

UPDATE: Eu encontrei um bug onde, se você selecionar o (s) arquivo (s) e, em seguida, vá para selecionar novamente, mas em vez disso, cancelar os arquivos nunca são desmarcados como ele aparece. Então atualizei meu código para consertar isso.

  .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] ); } }); } } }); 

Tente isso, isso está funcionando para mim em JS angular

  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);