27 votes

Jquery Draggable et Backbone.js obtiennent une référence au modèle de backbone de l'intérieur du rappel de succès largable

J'ai une épine dorsale modèle de vue que je me suis rendu ici, et de le rendre déplaçable avec jquery ui.

render: ->
$(this.el).attr('class', 'item').html(this.template(this.options.model.toJSON() ))
viewmodel = this
$(this.el).draggable
    revert: true
    drag: () ->
        console.log(viewmodel)

Ci-dessus, j'ai viewmodel disponible et pouvez la supprimer de la dom, l'appel de méthodes sur son modèle, etc. Mais ce que je veux, c'est faire glisser ce modèle de vue dans un drop, contenant, comme une poubelle, et ensuite appeler un peu de la vue du modèle, de méthodes et de le retirer de la DOM.

Ce que je vois, cependant, est la méthode de rappel pour lorsqu'un objet est tombé dans un conteneur serait:

$(function() {
    $("#trash").droppable({
        drop: function(event, ui) {
          console.log(ui.draggable);
        }
    });
});

Donc, je suis en mesure de voir l'interface utilisateur.déplaçable et retirez-le du DOM, mais je n'ai pas de référence à son modèle de vue. Suis-je en train de faire quelque chose de mal? Aucun moyen de contourner cela?

40voto

Christopher Scott Points 1405

Je pense avoir rencontré le même problème; au lieu d'ajouter des métadonnées à l'élément ou de le stocker globalement, je viens de stocker une référence à la vue réelle elle-même sur l'élément DOM, qui vous donne alors accès au modèle et à toutes les informations dont vous avez besoin à partir de là.

 window.MyDraggableView = Backbone.View.extend({
    initialize: function(){
        $(this.el).draggable();
        $(this.el).data("backbone-view", this);
    }
});

window.MyDropTarget = Backbone.View.extend({
    initialize: function(){
        $(this.el).droppable({
            drop: function(ev, ui){
                // get reference to dropped view's model
                var model = $(ui.draggable).data("backbone-view").model;
            },
        });
    },
});
 

18voto

Elf Sternberg Points 9764

J'ai eu ce problème. Je l'ai résolu ainsi: Donnez à la cible cible une référence à la collection de modèles. Définissez une propriété data-cid="<%= cid %>" sur le draggable. Vous pouvez maintenant rechercher le modèle dans la collection à partir du $(ui.draggable).data('cid') . Étant donné que l'épine dorsale affirme que les CID sont uniques, vous pouvez même analyser une collection de collections, au cas où il y aurait plusieurs classes de modèle que vous voudriez être traçables.

10voto

Brennan Roberts Points 358

L'approche que j'utilise consiste à passer l'événement de la droppable à la draggable via un événement personnalisé.

 var DroppableView = Backbone.View.extend({
  events: { 'drop': 'dropHandler' },
  initialize: function() { this.$el.droppable(); },
  dropHandler: function(e, ui) { ui.draggable.trigger('drop:dropview'); }
})

var DraggableView = Backbone.View.extend({
  events: { 'drop:dropview': 'dropviewDropHandler'},
  initialize: function(){ this.$el.draggable(); },
  dropviewDropHandler: function() { this.doSomething(); }
});
 

Cela vous permet d'exécuter le gestionnaire de dépôt dans le contexte de la vue déplacée, ce qui est souvent plus utile que de l'exécuter dans le contexte de la vue supprimable.

1voto

abstraktor Points 521

Nous avons résolu ce problème avec une propriété globale qui est placé dans l'application-noms, appelé le faisant glisser.

Comme il n'y a qu'une seule vue glissé à un moment, le faisant glisser la vue se lie à l'événement glisser et écrit son propre modèle dans la fenêtre.en faisant glisser.

Quand il fait tomber sur un drop point de vue, que la vue devient l'actuel glisser-modèle par le biais de glisser variable.

btw, cette propriété peut être mieux placé au sein de la global accessible de l'application de l'espace de noms au lieu de directement de l'ajouter à la fenêtre. C'était d'Application.Vue.dans notre application.

Comme ceci:

dragging = null;

draggableview = new Backbone.View.extend({

    //...
    initialize: function() {

        //...
        $(this.el).bind("dragStart",
        function() {
            window.dragging = this.model;
        },
        this);

        //remove reference for garbage collection purpose
        $(this.el).bind("dragStop",
        function() {
            delete window.dragging;
        },
        this);
    },

});

droppableview = new Backbone.View.extend({

    //...
    initialize: function() {

        //...
        $(this.el).bind("drop",
        function() {
            var draggedmodel = window.dragging;
            delete window.dragging;
            // for garbage collection purpose
            //do funky stuff
            alert("You dropped " + draggedmodel.get('title') + " on " + this.el.get('title'));
            //...
        },
        this);
    },
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X