Backbone.js jQuery&;主干:在特定条件下,如何在drop事件上附加视图

Backbone.js jQuery&;主干:在特定条件下,如何在drop事件上附加视图,backbone.js,backbone-views,backbone-events,jquery-droppable,jquery-draggable,Backbone.js,Backbone Views,Backbone Events,Jquery Droppable,Jquery Draggable,我有我的CanvasModel的以下视图,用户可以从工具栏上拖放各种小部件。每当将某个内容放到画布视图中时,一个新的WidgetView实例就会附加到DOM中 最近附加的小部件也是可拖动的,以便用户将其放置在画布中任何他想要的位置。问题是,只要删除最近附加的小部件,就会附加另一个WidgetView实例 var CanvasView = Backbone.View.extend ({ tagName: 'section', className: 'canvas', e

我有我的CanvasModel的以下视图,用户可以从工具栏上拖放各种小部件。每当将某个内容放到画布视图中时,一个新的WidgetView实例就会附加到DOM中

最近附加的小部件也是可拖动的,以便用户将其放置在画布中任何他想要的位置。问题是,只要删除最近附加的小部件,就会附加另一个WidgetView实例

var CanvasView = Backbone.View.extend ({
    tagName: 'section',
    className: 'canvas', 

    events: {
    'drop': 'instantiateWidget'
    },

    initialize: function(){
        this.$el.droppable({});
    },

    render: function(){
        return this;
    },

    instantiateWidget: function() {
        this.$el.on("drop", function(event, ui){}).append(new WidgetView({model: myWidget}).render().el);   
    }
});     

我只想实例化一个从工具栏拖到画布上的小部件(它们有一个“拖拽”类)。是否有一种方法可以“过滤”拖放侦听器,这样CanvasView仅在拖放的项目具有“已拖动”类或已从工具栏拖动时才会实例化小部件?

我不熟悉特定的拖放事件,但要回答您的问题:

有没有办法“过滤”掉监听程序

答案是肯定的。所有事件处理程序都会传递一个事件对象,您可以查看它的详细信息(特别是它的
target
属性),以确定哪个DOM元素触发了事件

但是,我注意到代码中有一个更重要的问题:您似乎未正确连接事件处理程序。你正在做:

this.$el.on("drop", function(event, ui){}).append(new WidgetView({model: myWidget}).render().el);
它将连接一个不做任何事情的事件处理程序,然后立即附加一个新的小部件。我想你要做的是:

this.$el.on("drop", function(event, ui){
    $(event.target).append(new WidgetView({model: myWidget}).render().el)
});
但这似乎是错误的,因为您正在绑定一个事件处理程序以响应另一个事件。我想你想要的是:

instantiateWidget: function() {
   this.$el.append(new WidgetView({model: myWidget}).render().el);   
}
因此,回到您原来的问题,如果您想在新代码中检查导致事件的元素,它将如下所示:

instantiateWidget: function(e) {
   if ($(e.target).is(':not(canvas)') return;
   this.$el.append(new WidgetView({model: myWidget}).render().el);   
}

或者,您可以完全避免这种情况,只需将事件连接上的选择器设置为只针对由所需元素生成的事件(请记住,事件连接只使用普通的jQuery选择器)。

正如@MachineHost指出的,我的语法中有一个致命错误。然而,根据我从代码中了解到的情况,我们检查事件目标,如果它不是“画布”,则什么也不会发生,如果是,则小部件被渲染到其中。 不幸的是,事实并非如此,因为实例化的小部件也可以在画布中拖动(供用户定位),即使使用您的实现,我认为拖动/拖放实例化的小部件也会在画布中导致更多的实例化(一旦它们被丢弃)

基本上,我想做的是检查工具栏中被拖动的元素是否有一个“被拖动”的类(它是这样做的),如果是这样的话,只有在画布中实例化一个小部件,这将防止新实例化的小部件在画布上被拖动定位时导致进一步的实例化(实例化的小部件没有一个被拖动的类)

为了实现类似的功能,我深入研究了jQuery事件。有一个很好的事件叫做“dragstop”,我可以用下面的方式来获得我想要的

$('section#toolbar').children.on("dragstop", function(event, ui){})
问题是,在dragstop的函数中,我需要引用drop事件

 if ($(e.target).is('canvas')) this.$el.append(new WidgetCanvasView({model: myWidget}).render().el);
但显然这也不行…(需要绑定事件等)
不过,感谢您的回答,这让我思考并深入挖掘事件,以及如何绑定事件等。希望我能找到解决此问题的方法!

感谢您的回复。不幸的是,您的代码示例不会在下面这行中运行(意外的是)。$el.append(新的WidgetView({model:myWidget}).render().el);