2

ここでNoobはbackbone.jsを学習しています。シンプルな横型メニューを作成しようとしていました(各メニュー項目はモデルで、メニュー全体がコレクションです)。どのメニュー項目がクリックされたか知りたいのですが。menuItemViewで、「click a」イベントを「clicked」関数にバインドしましたが、クリックしても発生しません。私が見つけたこれに最も近い解決策は次のとおりです:http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/そして、私は同様の機能を複製しようとしました...私はそれをほぼ同じようにコピーしたと思いますが、それでもそれを機能させることができないようです。どのモデル/アイテムがクリックされたかを検出する問題に対処しているように見えるすべての投稿を調べましたが、どれも役に立たなかったようです。どんな助けでもいただければ幸いです。クリック可能なメニューとそのIDの取得は、単純なjqueryの方がおそらくはるかに簡単であることを知っていますが、バックボーンを学習するための例としてこれを使用すると思いました。

HTML

<header>
<ul id="nav">
</ul>
</header>

JAVASCRIPT

(function($) {

window.app = window.app || {};

//Goal:if selected=true, menu item should be highlighted
MenuItem = Backbone.Model.extend({
    label: "Default Label",
    selected: false,
    id: 0
});

MenuList = Backbone.Collection.extend({
    model: MenuItem,
    initialize: function(models, options) {
        //nothing ... yet
    }
});


//View for a single item. Returns el that looks like:
//  <li id='4' class='false'><a href='#4'> Item 4 </a> </li?
MenuItemView = Backbone.View.extend({
    tagName: "li",

    render: function() {
        var id  = this.model.get("id");
        var cls = this.model.get("selected");
        var lbl = this.model.get("label");
        $(this.el).attr('id', id).addClass(cls.toString());
        $(this.el).html("<a href=#" + id + " >" + lbl + "</a> </li>");
        return this; //recommended as this enables calls to be chained.
    },

    events: {
        "click a": "clicked" //Firebug shows 'a' element bound to
                             //native 'click' and not 'clicked'. WHY?
    },

    clicked: function(ev){
        alert($(ev.target).text()); //NOT HAPPENING :-(
        //do something to highlight menu item via css stuff.
    }
});

MenuListView = Backbone.View.extend({
    el: $("header > ul"),

    initialize: function() {
        this.menulist = new MenuList(null, { view: this });
        _.bindAll(this, "renderItem");
    },

    renderItem: function(model) {
        var menuitemView = new MenuItemView({ model: model });
        menuitemView.render();
        $(this.el).append(menuitemView.el);
    },

    render: function() {
        this.collection.each(this.renderItem);
    },

    setActivePage: function(ev) {
        alert($(ev.target).text());
        window.app.footerview.updatePageNumber(10);
    }
});


var items = new MenuList([
{id: 1, label: "item 1", selected: true},
{id: 2,label: "item 2",selected: false},
{id: 3,label: "item 3",selected: false},
{id: 4,label: "item 4",selected: false}
]);


window.app.menuview = new MenuListView({ collection: items });
window.app.menuview.render();
$("header").html(window.app.menuview.el);

})(jQuery);

この実行例はjsfiddleで見ることができます:..http://jsfiddle.net/gopal_a/4uzcb/3/を参照してください

4

1 に答える 1

0

あなたの問題はここにあります:

$("header").html(window.app.menuview.el);

次のように定義したので、あなたwindow.app.menuview.elはすでにDOMにいます。

el: $("header > ul")

あなたが$('header').html(...)、あなたはすでに入っているものを片付けて、<header>それをあなたのel;に置き換えています。ただし、.html()呼び出しにより、ビューのイベントを処理するためにBackboneがインストールするイベントデリゲーターが強制終了されます。その結果、DOMに適切なHTMLが作成されますが、それらにイベント処理がアタッチされていません。

あなたをドロップする$("header").html(window.app.menuview.el)と、物事が機能し始めます。

余談ですが、言う必要はありません$(this.el)。バックボーンビューはすでにthis.$el定義されているので、代わりに使用できますthis.$el

于 2012-07-09T20:54:11.473 に答える