1

jsfiddle での私のアプリの例を次に示します: http://jsfiddle.net/GWXpn/1/

問題は、クリック イベントがまったく発生していないことです。コンソールに JS エラーが表示されません。

最初に、各項目をクリック可能にする必要がある場合に、いくつかの項目を含む順序付けられていないリストを表示したいと考えました。これは私がしたことです:

var FooModel = Backbone.Model.extend({});

var ListView = Backbone.View.extend({
        tagName: 'ul', // name of (orphan) root tag in this.el
        initialize: function() {
            _.bindAll(this, 'render'); // every function that uses 'this' as the current object should be in here
        },
        render: function() {
            for (var i = 0; i < 5; i++) {
                var view = new SingleView({
                    model: new FooModel()
                });
                $(this.el).append(view.render().el);
            }
            return this; // for chainable calls, like .render().el
        }
    });

      var SingleView = Backbone.View.extend({
        tagName: 'li', // name of (orphan) root tag in this.el
        initialize: function() {
            _.bindAll(this, 'render', 'click'); // every function that uses 'this' as the current object should be in here
        },
        events: {
            "click": "click"
        },
        click: function(ev) {
            console.log("aaa");
            alert(333);

        },
        render: function() {
            $(this.el).append("aaa");
            return this; // for chainable calls, like .render().el
        }
    });

アプリを複数のモジュール (ヘッダー、ボディ、フッター) に分割したかったので、抽象モデルを作成し、そこからモジュールを拡張しました。

var AbstractModule = Backbone.Model.extend({
    getContent: function () {
        return "TODO";
    },
    render: function () {
        return $('<div></div>').append(this.getContent());
    }
});
var HeaderModule = AbstractModule.extend({
    id: "header-module",
});
var BodyModule = AbstractModule.extend({
    id: "body-module",
    getContent: function () {

        var listView = new ListView();

        return $("<div/>").append($(listView.render().el).clone()).html();
    }
});
var ModuleCollection = Backbone.Collection.extend({
    model: AbstractModule,
});

次に、メイン ビューを作成し、そのすべてのサブビューをレンダリングしました。

var AppView = Backbone.View.extend({
    el: $('#hello'),
    initialize: function (modules) {
        this.moduleCollection = new ModuleCollection();
        for (var i = 0; i < modules.length; i++) {
            this.moduleCollection.add(new modules[i]);
        }
    },
    render: function () {
        var self = this;
        _(this.moduleCollection.models).each(function (module) { // in case collection is not empty
            $(self.el).append(module.render());
        }, this);
    }
});

var appView = new AppView([HeaderModule, BodyModule]);
appView.render();

理由はありますか?

4

1 に答える 1

3

You have two bugs in one line:

return $("<div/>").append($(listView.render().el).clone()).html();

First of all, clone doesn't copy the events unless you explicitly ask for them:

Normally, any event handlers bound to the original element are not copied to the clone. The optional withDataAndEvents parameter allows us to change this behavior, and to instead make copies of all of the event handlers as well, bound to the new copy of the element.
[...]
As of jQuery 1.5, withDataAndEvents can be optionally enhanced with deepWithDataAndEvents to copy the events and data for all children of the cloned element.

You're cloning the <ul> here so you'll want to set both of those flags to true.

Also, html returns a string and strings don't have events so you're doubling down on your event killing.

I don't understand why you're cloning anything at all, you should just return the el and be done with it:

    return listView.render().el;

If you insist on cloning, then you'd want something like this:

    return $(listView.render().el).clone(true, true);

but that's just pointless busy work.

BTW, 'title' and 'Title' are different model attributes so you'll want to say:

console.log(this.model.get("title") + " clicked");

instead of

console.log(this.model.get("Title") + " clicked");

Also, Backbone collections have a lot of Underscore methods mixed in so don't mess with a collection's models directly, where you're currently saying:

_(this.moduleCollection.models).each(...)

just say:

this.moduleCollection.each(...)

And as Loamhoof mentions, 0.3.3 is ancient history, please upgrade to newer versions of Backbone, Underscore, and jQuery. You should also read the change logs so that you can use newer features (such as this.$el instead of $(this.el), fewer _.bindAll calls, listenTo, ...).

Partially Corrected Demo (including updated libraries): http://jsfiddle.net/ambiguous/e4Pba/

I also ripped out the alert call, that's a hateful debugging technique that can cause a huge mess if you get into accidental infinite loops and such, console.log is much friendlier.

于 2013-06-10T21:53:48.733 に答える