2012-01-19 18 views
3

私はBackbone.jsを初めて使用しようとしていますが、何か問題があります。私の問題は、私がバックボーンの働きを理解していないか、単なるコードの問題であるかどうか分かりません。Backbone.jsホバーイベントがトリガーされない

私はダイナミックメニューを作成しようとしていますが、項目でメインメニューバーを作成するのに問題はありませんが、メニュー項目の1つをホバーするたびにホバーイベントをトリガーすることはできません。

ビュー

var MenuView = Backbone.View.extend({ 
    initialize: function(items) { 
     this.menu = items; 
     //Main navigation bar 
     this.el = $("#main-nav"); 
     this.trigger('start'); 
     this.render(); 
    }, 
    render: function() { 
     var me = this; 
     _.each(this.menu, function(mi) { 
      mi.render(me.el); 
     }); 
     return this; 
    }, 
    handleHover: function(e) { 
     console.debug(e); 
    } 
}); 

var MenuItemView = Backbone.View.extend({ 
    tagName: 'li', 
    className:'menu-item', 
    events: { //none of these work 
     'hover a':'handleHover', 
     'mouseover a':'handleHover', 
     'mouseover':'handleHover', 
     'click': 'handleHover', 
     'click a': 'handleHover' 
    }, 
    initialize: function(mi) { 
     this.menuItem = mi; 
     this.el = $("<li class=\"menu-item\"></li>") 
    }, 
    render: function(parent) { 
     this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>'); 
     parent.append(this.el); 
     return this; 
    }, 

    handleHover: function(ev) { 
     console.debug("Hovering! " + ev + this.menuItem.get("cid")); 
     console.debug(ev); 
     return false; 
    } 
}); 

モデル

var MenuItem = Backbone.Model.extend({ 
    defaults: { 
     parent: null, 
     children: [], 
     link: "", 
     text: "" 
    } 
}); 

スタートアップコード

$(document).ready(function() { 
    var menu = new MenuView([ 
     new MenuItemView(new MenuItem({link: "/", text: "Home"})), 
     new MenuItemView(new MenuItem({link: "/", text: "Users"})), 
     new MenuItemView(new MenuItem({link: "/", text: "Configuration"})) 
    ]); 
}); 

すべてのヘルプは理解されるであろう!

ありがとうございます! MenuItemViewビューにinitialize方法のel外の定義を取って、それは動作しますが、その同じ要素がビューのすべてのインスタンスに再利用されますので、後に、私は変更しなければならなかった

更新

[OK]を、次のコードを視野に、それは私がそれ望むように動作させるために:

var MenuItemView = Backbone.View.extend({ 

    events: { //none of these work 
     'hover a':'handleHover', 
     'mouseover a':'handleHover', 
     'mouseover':'handleHover', 
     'click': 'handleHover', 
     'click a': 'handleHover' 
    }, 
    el: $('<li class="menu-item"></li>'), 
    initialize: function(mi) { 
     this.menuItem = mi; 
     this.el = $(this.el).clone(true); 
    }, 
    render: function(parent) { 
     this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>'); 
     parent.append(this.el); 
     return this; 
    }, 

    handleHover: function(ev) { 
     console.debug("Hovering! " + ev + this.menuItem.get("cid")); 
     console.debug(ev); 
     return false; 
    } 
}); 

WNY私は新しいインスタンス上で要素のクローンを作成しなければなりませんか?

+0

なぜあなたの 'el'をクローンする必要がありますか? '$( '

')'が評価されたときに、あなたはあなたの答えを得るでしょう。 –

+0

'initialize'メソッドで' el'の要素を作成した場合、イベントはトリガされません。どのように解決できますか? – Deleteman

答えて

8

Re:なぜ新しいインスタンスに要素をクローンする必要がありますか?

根本的な問題はここです:

var MenuItemView = Backbone.View.extend({ 
    // ... 
    el: $('<li class="menu-item"></li>'), 

$('<li class="menu-item"></li>')コールは、あなただけの1 $('<li>')MenuItemViewのすべてのインスタンス間で共有されているで終わるようMenuItemViewが定義されているときに実行されます。あなたがinitializeまたはrenderelを作成した場合、あなたはdelegateEventsを用いて手でイベントをバインドする必要があります

デフォルトでは、delegateEventsはあなたのためのビューのコンストラクタ内で呼び出されます[...]

したがって、this.elを作成する場合は、this.delegateEvents()に電話する必要があります。たとえば:

var MenuItemView = Backbone.View.extend({ 
    // ... 
    render: function() { 
     this.el = $('<li class="menu-item"><a>' + this.cid + '</a></li>'); 
     this.delegateEvents(); 
     return this; 
    }, 
    //... 
}); 

デモ:あなたのwithDataAndEventsフラグをcloneあなたthis.el場合http://jsfiddle.net/ambiguous/RPqMh/2/

しかし、その後、あなたは問題ないはずです。

var MenuItemView = Backbone.View.extend({ 
    el: $('<li class="menu-item"></li>'), 
    // ... 
    initialize: function() { 
     this.el = this.el.clone(true); 
     this.el.append('<a>' + this.cid + '</a>'); 
    }, 
    //... 
}); 

デモ:http://jsfiddle.net/ambiguous/hCW3F/1/

しかし、this.el.clone()の場合は、delegateは、クローンに拘束されることはありません。

var MenuItemView = Backbone.View.extend({ 
    el: $('<li class="menu-item"></li>'), 
    // ... 
    initialize: function() { 
     this.el = this.el.clone(); 
     this.el.append('<a>' + this.cid + '</a>'); 
    }, 
    // ... 
}); 

デモ:http://jsfiddle.net/ambiguous/KZNPA/

しかし、あなたはあなた自身のdelegateEventsの呼び出しを追加した場合、あなたは大丈夫だろう:

var MenuItemView = Backbone.View.extend({ 
    el: $('<li class="menu-item"></li>'), 
    // ... 
    initialize: function() { 
     this.el = this.el.clone(); 
     this.el.append('<a>' + this.cid + '</a>'); 
    }, 
    render: function() { 
     this.delegateEvents(); 
     return this; 
    }, 
    // ... 
}); 

デモ:http://jsfiddle.net/ambiguous/KZNPA/1/

+0

説明をいただきありがとうございます!それは私のためにすべてのものをクリアしました:) – Deleteman

+0

@Deleteman:私は私のメモを共有したので、私は自分の頭の中でそれがすべて明確であったことを確認しなければなりません:) –

2

あなたがこのプロパティを必要としないように私には思える:あなたはthis.el = $('<li class="menu-item"></li>')を指定した場合MenuItemViewで

tagName: 'li', 
className:'menu-item' 

を。

+0

はい、テスト中にそのコードが追加されて問題が解決するかどうかを確認しましたが、それはできませんでした。 – Deleteman

+0

はい、私もチェックしました。修正しなかった。とにかく 'tagName'と' className'の代わりに 'el:$( '

')'を直接定義するとうまくいくはずです。 – dfsq

+0

はい、 'initialize'メソッドの外で' el'を定義すると(kind of)、同じ要素がビューのすべてのインスタンスで再利用されます。私はあなたにあなたを示す更新を書くでしょう... – Deleteman

9

ホバーは通常のイベントではなく、jqueryによって提供される '便利な'イベントです。これは、マウスセンターとマウスリーブの組み合わせです。

マウスを動かすのではなくmouseleaveにバインドすると、必要な処理が実行されます。

関連する問題