AngularJS ficheiro arrastar e largar na Directiva

Este exemplo faz praticamente o que eu gostaria de fazer em Angular-js: HTML5 File API .

eu tenho tentado pesquisar alguns exemplos de diretivas no entanto eu encontrei um exemplo antigo que fazem uso massivo de DOM ou não são escritos para 1.0.4 Angular.

basicamente este é o código js puro:

var holder = document.getElementById('holder'),
    state = document.getElementById('status');

if (typeof window.FileReader === 'undefined') {
  state.className = 'fail';
} else {
  state.className = 'success';
  state.innerHTML = 'File API & FileReader available';
}

holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
  this.className = '';
  e.preventDefault();

  var file = e.dataTransfer.files[0],
      reader = new FileReader();
  reader.onload = function (event) {
    console.log(event.target);
    holder.style.background = 'url(' + event.target.result + ') no-repeat center';
  };
  console.log(file);
  reader.readAsDataURL(file);

  return false;
};

a única maneira possível de pensar é criar uma directiva que faça

edo.directive('fileDrag', function () {
  return {
    restrict: 'A',
    link: function (scope, elem) {
      elem.bind('ondrop', function(e){
        e.preventDefault();
        var file = e.dataTransfer.files[0], reader = new FileReader();
          reader.onload = function (event) {
          console.log(event.target);
          holder.style.background = 'url(' + event.target.result + ') no-repeat center';
        };
        console.log(file);
        reader.readAsDataURL(file);

        return false;
      });
    }
  };
});
[[3]} No entanto (1) não funcionou, (2) antes que eu corrigi-lo eu gostaria de saber se alguma coisa existe ou se estou a fazê-lo correctamente,

qualquer dica ou ajuda é muito apreciada.

Author: Kevin Hakanson, 2013-02-05

2 answers

Para consolidar os comentários numa resposta, mude ondrop para drop, Adicione e.stopPropagation(), mude holder para elem.

edo.directive('fileDrag', function () {
  return {
    restrict: 'A',
    link: function (scope, elem) {
      elem.bind('drop', function(e){
        e.preventDefault();
        e..stopPropagation();
        var file = e.dataTransfer.files[0], reader = new FileReader();
          reader.onload = function (event) {
          console.log(event.target);
          elem.style.background = 'url(' + event.target.result + ') no-repeat center';
        };
        console.log(file);
        reader.readAsDataURL(file);

        return false;
      });
    }
  };
});
Eu estava a fazer algo semelhante e aqui está a minha solução de trabalho.

HTML

app.directive("dropzone", function() {
    return {
        restrict : "A",
        link: function (scope, elem) {
            elem.bind('drop', function(evt) {
                evt.stopPropagation();
                evt.preventDefault();

                var files = evt.dataTransfer.files;
                for (var i = 0, f; f = files[i]; i++) {
                    var reader = new FileReader();
                    reader.readAsArrayBuffer(f);

                    reader.onload = (function(theFile) {
                        return function(e) {
                            var newFile = { name : theFile.name,
                                type : theFile.type,
                                size : theFile.size,
                                lastModifiedDate : theFile.lastModifiedDate
                            }

                            scope.addfile(newFile);
                        };
                    })(f);
                }
            });
        }
    }
});
div[dropzone] {
    border: 2px dashed #bbb;
    border-radius: 5px;
    padding: 25px;
    text-align: center;
    font: 20pt bold;
    color: #bbb;
    margin-bottom: 20px;
}
<div dropzone>Drop Files Here</div>
 22
Author: Kevin Hakanson, 2015-10-19 17:24:35

Prevenir eventos predefinidos e obter o ficheiro do evento original. Tudo pode ser implementado na Directiva. Você deve passar a função, para trabalhar com arquivos para atribuir on-file-drop. Também a classe 'dragging' é adicionada ao elemento dropzone enquanto arrasta. Em vista, parece-se com isto:

<div file-dropzone on-file-drop="myFunction">This is my dropzone </div>

Directiva:

function fileDropzoneDirective() {
    return {
        restrict: 'A',
        link: fileDropzoneLink
    };
    function fileDropzoneLink($scope, element, attrs) {
        element.bind('dragover', processDragOverOrEnter);
        element.bind('dragenter', processDragOverOrEnter);
        element.bind('dragend', endDragOver);
        element.bind('dragleave', endDragOver);
        element.bind('drop', dropHandler);

        function dropHandler(angularEvent) {

            var event = angularEvent.originalEvent || angularEvent;
            var file = event.dataTransfer.files[0];
            event.preventDefault();
            $scope.$eval(attrs.onFileDrop)(file);

        }
        function processDragOverOrEnter(angularEvent) {
            var event = angularEvent.originalEvent || angularEvent;
            if (event) {
                event.preventDefault();
            }
            event.dataTransfer.effectAllowed = 'copy';
            element.addClass('dragging');
            return false;
        }

        function endDragOver() {
            element.removeClass('dragging');
        }
    }
}
 2
Author: Andrew Koval, 2017-04-14 14:20:22