Jquery Draggable 和 Backbone.js 从可放置成功回调内部获取对骨干模型的引用
Posted
技术标签:
【中文标题】Jquery Draggable 和 Backbone.js 从可放置成功回调内部获取对骨干模型的引用【英文标题】:Jquery Draggable and Backbone.js getting reference to backbone model from inside the droppable success callback 【发布时间】: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 中删除,但我没有参考它的视图模型。难道我做错了什么?有什么办法可以解决这个问题?
【问题讨论】:
【参考方案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);
,
);
【讨论】:
以上是关于Jquery Draggable 和 Backbone.js 从可放置成功回调内部获取对骨干模型的引用的主要内容,如果未能解决你的问题,请参考以下文章