web-dev-qa-db-fra.com

Directive glisser-déposer du fichier AngularJS

Cet exemple fait à peu près ce que je voudrais porter dans Angular-js: API de fichier HTML5 .

J'ai essayé de google un exemple de directives mais j'ai trouvé un vieil exemple qui utilise massivement le DOM ou n'est pas écrit pour Angular 1.0.4.

Fondamentalement, c'est le code js pur:

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

La seule façon dont je peux penser est de créer une directive qui

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

Cependant (1) cela n'a pas fonctionné, (2) avant de le réparer, je voudrais savoir si quelque chose existe ou si je le fais correctement,

Tout indice ou aide est très apprécié.

20
piggyback

Pour consolider les commentaires dans une réponse, remplacez ondrop par drop, ajoutez e.stopPropagation(), remplacez holder par 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;
      });
    }
  };
});

Je faisais quelque chose de similaire et voici ma solution de travail:

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
Kevin Hakanson

Empêcher les événements par défaut et obtenir le fichier de l'événement d'origine. Tout peut être implémenté dans la directive. Vous devez passer la fonction, pour travailler avec des fichiers à attribuer lors du dépôt de fichier. La classe "glisser" est également ajoutée à l'élément dropzone pendant le glisser. En vue, cela ressemble à ceci:

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

directif:

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
Andrew Koval