【问题标题】:Jquery Draggable and Backbone.js getting reference to backbone model from inside the droppable success callbackJquery Draggable 和 Backbone.js 从可放置成功回调内部获取对骨干模型的引用
【发布时间】:2011-11-11 19:09:19
【问题描述】:

我有一个主干视图模型,我在这里渲染它并使它可以用 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 中删除,但我没有参考它的视图模型。难道我做错了什么?有什么办法可以解决这个问题?

【问题讨论】:

    标签: jquery-ui backbone.js jquery-ui-draggable jquery-ui-droppable


    【解决方案1】:

    我想我遇到了同样的问题;我没有将元数据添加到元素或将其全局存储,而是将对实际视图本身的引用存储在 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;
                },
            });
        },
    });
    

    【讨论】:

    • 这是 imo 最好的方法
    • 我喜欢这个答案。但它会在大多数浏览器上正确收集垃圾吗(因为有循环引用)?
    • 我不是 100% 确定,但我认为 JS 对象和 DOM 节点之间的循环引用只是旧 IE(7 及以下)的问题。不过,这可能值得研究。另外我认为 jQuery 数据也可以缓解这个问题。
    • 这不是脱离了 Backbone.js 框架吗?
    【解决方案2】:

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

    【讨论】:

    • 所以我可以获取集合中的项目,但是获取视图模型本身呢?运行 collection.remove(id) 会将其从集合中删除,但不会从我的视图中删除。
    • 将集合上的 'remove' 事件绑定到从 DOM 中删除视图的视图方法。
    • 您必须跟踪视图,将它们放入数组或 CID 跟踪的对象中。
    • 非常感谢。这完全有效,并且以我看待 javascript 的方式改变了游戏规则。 :)
    【解决方案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(); }
    });
    

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

    【讨论】:

    • +1 的想法是让它在可拖动而不是可放置的上下文中执行。
    • 这当然是这个线程上最好的解决方案。您还可以将DroppableView 实例作为drop:dropview 的参数传递,dropviewDropHandler 将可以访问DroppableView 和 DraggableView` 实例。
    【解决方案4】:

    我们通过放置在应用命名空间中的全局属性(称为拖动)解决了这个问题。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2014-03-15
      • 1970-01-01
      相关资源
      最近更新 更多