Подтвердить что ты не робот

Jquery Draggable и Backbone.js получают ссылку на базовую модель изнутри обратного вызова с возможностью отказа

У меня есть модель базового вида, которую я просматриваю здесь, и перетаскивая ее с помощью 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)

Выше, у меня есть viewmodel и вы можете удалить его из dom, вызвать методы на своей модели и т.д. Но я хочу перетащить эту модель представления в контейнер с возможностью удаления - например, с помощью мусора, а затем вызвать некоторые из методов модели представления и удалите их из DOM.

Что я вижу, это метод обратного вызова, когда элемент упал в контейнер:

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

Итак, я могу видеть ui.draggable и удалить его из DOM, но у меня нет ссылки на его модель представления. Я делаю что-то неправильно? Любой способ обойти это?

4b9b3361

Ответ 1

У меня была эта проблема. Я решил это так: Дайте целевой цели ссылку на коллекцию моделей. Задайте свойство data-cid="<%= cid %>" для перетаскиваемого объекта. Теперь вы можете найти модель в коллекции из $(ui.draggable).data('cid'). Поскольку базовая группа утверждает, что идентификаторы CID уникальны, вы даже можете отсканировать коллекцию коллекций, если есть несколько классов моделей, которые вы хотели бы сбрасывать.

Ответ 2

Я думаю, что столкнулся с той же проблемой; вместо того, чтобы добавлять метаданные к элементу или хранить его во всем мире, я просто сохранил ссылку на фактическое представление непосредственно на элемент DOM, который затем дает вам доступ к модели и любую информацию, которую вам нужно оттуда.

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 model
                var model = $(ui.draggable).data("backbone-view").model;
            },
        });
    },
});

Ответ 3

Подход, который я использую, заключается в передаче события из droppable в draggable через настраиваемое событие.

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

Это позволит вам выполнить обработчик перетаскивания в контексте перетаскиваемого представления, что часто более полезно, чем выполнение его в контексте раскрывающегося вида.

Ответ 4

Мы решили эту проблему с глобальным свойством, которое помещается в пространство имен приложений, называемое dragging.

Поскольку в одно время перетаскивается только один вид, перетаскивающий вид привязывается к событию перетаскивания и записывает свою собственную модель в window.dragging.

Когда он падает на раскрывающемся представлении, это представление получает текущую модель перетаскивания с помощью этой переменной перетаскивания.

btw это свойство может быть лучше помещено в глобальное доступное пространство имен приложений вместо прямого добавления его в окно. Это наш App.View.tool в нашем приложении.

Вот так:

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