【问题标题】:jQuery & Backbone: How to append a view on drop event, under certain conditionsjQuery & Backbone:如何在特定条件下在 drop 事件上附加视图
【发布时间】:2013-01-02 15:59:57
【问题描述】:

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

最近添加的小部件也是可拖动的,以便用户将其放置在画布中的任何位置。问题是,只要删除了最近附加的 Widget,就会附加另一个 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 将仅在放置的项目具有“拖动”类或已从工具栏拖动时实例化一个小部件?

【问题讨论】:

    标签: backbone.js backbone-views backbone-events jquery-droppable jquery-draggable


    【解决方案1】:

    我不熟悉那个具体的掉落事件,但回答你的问题

    有没有办法“过滤”drop listener

    答案是肯定的。所有事件处理程序都会传递一个事件对象,您可以查看它的详细信息(特别是其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 选择器)。

    【讨论】:

    • 感谢您的回复。不幸的是,您的代码示例不会在以下行中运行(Unexpected toke this) this.$el.append(new WidgetView({model: myWidget}).render().el);
    【解决方案2】:

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

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

    为了实现类似的东西,我深入研究了 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);
    

    但显然这也不起作用......(需要绑定事件等......) 不过感谢您的回答,它让我思考并更深入地研究事件,以及如何绑定它们等......希望我能找到解决这个问题的方法!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多