angulaire.bind() pour "drop" écouteur d'événement à ne pas se comporter correctement
J'ai un <div>
élément avec la directive dragAndDrop
définir comme un attribut:
<div ng-class="divClass" drag-and-drop>Drop files here</div>
(que d'un côté, et de moins en moins important à noter, ng-classe ne se comporte pas comme prévu, mais c'est un question distincte)
Ce que je voudrais, c'est pour les utilisateurs de glisser et déposer des fichiers à partir de leur bureau à la div. Dès lors, si, je utiliser angular.bind()
pour détecter la baisse de l'événement. Bien sûr, une fois qu'ils tombent, j'appelle e.stopPropagation()
et e.preventDefault()
, mais la page se poursuit avec la redirection de la page, peu importe. Ce que je fais mal qui empêcherait les deux méthodes mentionnées ci-dessus à partir de l'exécution?
dragAndDrop
directive:
directive('dragAndDrop', function() {
return {
restrict: 'A',
link: function($scope, elem, attr) {
elem.bind('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
//still can't get this one to behave:
//https://stackoverflow.com/q/15419839/740318
$scope.divClass = 'on-drag-enter';
});
elem.bind('dragleave', function(e) {
e.stopPropagation();
e.preventDefault();
$scope.divClass = '';
});
elem.bind('drop', function(e) {
var droppedFiles = e.dataTransfer.files;
//It's as though the following two methods never occur
e.stopPropagation();
e.preventDefault();
if (droppedFiles.length > 0) {
for (var i=0,ii=droppedFiles.length;i<ii;i++) {
$scope.files.push(droppedFiles[i]);
}
}
});
}
};
});
OriginalL'auteur Scott | 2013-03-20
Vous devez vous connecter pour publier un commentaire.
Angulaire ne sait pas quand les gestionnaires d'événements que vous avez enregistrés sont déclenchés, vous devez donc vous informer Angulaire que vous avez modifié la portée des variables. Vous le faites avec les
$s'appliquent
fonction.Quand il s'agit de la baisse de gestionnaire, vous êtes correct--les déclarations aprèsvar droppedFiles = e.dataTransfer.files;
ne sont jamais fonctionner à cause de l'erreur d'exécution que les résultats de l'instruction.e
est un jQuery événement, tandis que l'dataTransfer
est une propriété sur les événements DOM. Pour résoudre le problème, vous devez accéder à l'origine de l'événement par le biais de laoriginalEvent
propriété.Mise à jour
e.originalEvent
n'est nécessaire que si vous avez inclus jQuery avant angulaire, mais puisque vous ne l'avez pas fait lors de votre plnkr, cette solution n'était pas valide, je m'en excuse.Il semble que vous avez besoin d'opter pour déposer, par
preventDefault
de l'événement dragover (peut-être cela peut être fait dans d'autres événements--ne l'ai pas testé.)Mise à jour plnkr.
$scope.$apply()
, j'ai présumé que c'était inutile étant donné laangular.bind()
méthode de mettre sur l'élément permettrait de maintenir le champ d'application, lors de l'utilisation de quelque chose comme.addEventListener()
ouelem.ondrop = function()
ne le serait pas. Suis-je trompé?$scope.$apply
(vous avez manqué la$
) résout la classe css problèmes. (Va jeter un oeil à l'autre problème, quand je rentre à la maison.)Doh! Bonne prise. Curieusement, je me suis apparemment rappeler que d'essayer avant d'basé sur les avis précédents d'ailleurs. Je dois avoir fait une erreur ailleurs ou de ne pas essayer du tout. Peu importe, je vous remercie. Hâte d'être à la ondrop solution.
lorsqu'un
bind()
fonction de rappel fonctionne, il fonctionne "à l'extérieur" du Angulaire, parce quebind()
que des séries normales d'événements JavaScript de liaison, d'où la nécessité pour nous d'manuellement appel$apply()
. Il pourrait être agréable si Angulaire fourni une sorte debindApply()
ou " angularBind () méthode qui serait automatiquement appel$apply()
pour nous, après l'exécution de la fonction de rappel.Vous n'avez pas à définir la dropEffect, mais vous avez besoin d'arrêter de l'événement dragover, sinon la baisse de l'événement ne se déclenche pas.
OriginalL'auteur Martin