0

次の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は、ドロップされたアイテムに「ドラッグ」のクラスがあるか、ツールバーからドラッグされた場合にのみウィジェットをインスタンス化しますか?

4

2 に答える 2

2

私はその特定のドロップイベントに精通していませんが、あなたの質問に答えるために

ドロップリスナーを「フィルタリング」する方法はありますか

答えは、確かにそうです。すべてのイベントハンドラーにはイベントオブジェクトが渡され、その詳細(特にその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セレクターを使用するだけです)。

于 2013-01-02T21:34:48.380 に答える
0

@machineghostが指摘したように、構文に致命的なエラーがありました。ただし、コードから理解したことから、イベントターゲットをチェックし、それが「キャンバス」でない場合は何も起こりませんが、そうである場合はウィジェットがレンダリングされます。残念ながら、これは当てはまりません。インスタンス化されたウィジェットはキャンバス内でもドラッグ可能であり(ユーザーがそれらを配置するため)、実装を使用しても、インスタンス化されたウィジェットのドラッグ/ドロップによって、キャンバス内でより多くのインスタンス化が発生すると思います(彼らが落とされるとすぐに)。

基本的に私がやりたいのは、ツールバーからドラッグされた要素に「ドラッグされた」クラスがあるかどうかを確認し、ある場合は、ウィジェットをキャンバスにインスタンス化することです。これにより、新しくインスタンス化されたウィジェットが配置のためにキャンバスの周りにドラッグされている間、さらにインスタンス化を引き起こします(インスタンス化されたウィジェットにはドラッグされたクラスがありません)。

そのようなものを実装するために、私はjQueryイベントを少し掘り下げました。「ドラッグストップ」という素敵なイベントがあり、次のように使って欲しいものを手に入れることができます。

$('section#toolbar').children.on("dragstop", function(event, ui){})

問題は、dragstopの関数内で、dropイベントを参照する必要があることです。

 if ($(e.target).is('canvas')) this.$el.append(new WidgetCanvasView({model: myWidget}).render().el);

しかし、どうやらそれもうまくいかないようです...(イベントをバインドする必要があるなど)しかし、あなたの答えに感謝します、それは私にイベントをもっと深く考えさせ、掘り下げました、そしてそれらをバインドする方法など...うまくいけば私はこの問題を回避する方法を見つけます!

于 2013-01-03T15:35:26.623 に答える