27

我有一个主干视图模型,我在这里渲染并使用 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)

上面,我有可用的视图模型,可以将其从 dom 中删除,调用其模型上的方法等。但我想要将此视图模型拖到一个可放置的容器中——就像一个垃圾桶——然后调用一些视图模型的方法并将其从 DOM 中移除。

不过,我看到的是,将项目放入容器时的回调方法是:

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

所以,我可以看到 ui.draggable 并将其从 DOM 中删除,但我没有参考它的视图模型。难道我做错了什么?有什么办法可以解决这个问题?

4

4 回答 4

41

我想我遇到了同样的问题;我没有将元数据添加到元素或将其全局存储,而是将对实际视图本身的引用存储在 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's model
                var model = $(ui.draggable).data("backbone-view").model;
            },
        });
    },
});
于 2011-10-12T15:29:33.650 回答
18

我遇到过这个问题。我因此解决了它:为放置目标提供对模型集合的引用。在可拖动对象上设置一个属性data-cid="<%= cid %>"。现在您可以从$(ui.draggable).data('cid'). 由于主干断言 CID 是唯一的,因此您甚至可以扫描集合的集合,以防有多个模型类您希望被丢弃。

于 2011-09-07T03:00:08.020 回答
11

我使用的方法是通过自定义事件将事件从 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(); }
});

这让您可以在拖动视图的上下文中执行放置处理程序,这通常比在可放置视图的上下文中执行它更有用。

于 2012-05-11T19:36:22.947 回答
1

我们通过放置在 app-namespace 中的全局属性(称为拖动)解决了这个问题。

由于一次只有一个视图被拖动,因此拖动视图绑定到拖动事件并将自己的模型写入window.dragging。

当它被放置在可放置视图上时,该视图通过该拖动变量获取当前拖动模型。

顺便说一句,该属性可以更好地放置在全局可访问的应用程序命名空间中,而不是直接将其添加到 window.xml 中。这是我们应用程序中的 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);
    },
});
于 2011-09-20T12:05:18.733 回答