1

所以这是我在 jsfiddle 中的应用程序示例:http: //jsfiddle.net/GWXpn/1/

问题是点击事件根本没有被触发。我在控制台中没有收到任何 JS 错误。

首先,我想显示一个带有几个 if 项目的无序列表,每个项目都应该是可点击的。这就是我所做的:

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

一行中有两个错误:

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

首先,clone除非您明确要求,否则不会复制事件:

通常,绑定到原始元素的任何事件处理程序都不会复制到克隆。可选withDataAndEvents参数允许我们更改此行为,并改为制作所有事件处理程序的副本,绑定到元素的新副本。
[...]
从 jQuery 1.5 开始,withDataAndEvents可以选择增强deepWithDataAndEvents 以复制克隆元素的所有子元素的事件和数据。

您正在克隆<ul>此处,因此您需要将这两个标志都设置为true.

此外,html返回一个字符串,而字符串没有事件,所以你要加倍处理你的事件。

我不明白你为什么要克隆任何东西,你应该返回el并完成它:

    return listView.render().el;

如果你坚持克隆,那么你会想要这样的东西:

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

但这只是无意义的忙碌工作。

顺便说一句,'title'并且'Title'是不同的模型属性,所以你会想说:

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

代替

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

此外,Backbone 集合混合了很多Underscore 方法,因此不要models直接与集合混淆,您当前所说的是:

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

说啊:

this.moduleCollection.each(...)

正如 Loamhoof 提到的,0.3.3 是古老的历史,请升级到更新版本的 Backbone、Underscore 和 jQuery。您还应该阅读更改日志,以便您可以使用更新的功能(例如,this.$el而不是$(this.el),更少的_.bindAll调用listenTo,...)。

部分更正的演示(包括更新的库):http: //jsfiddle.net/ambiguous/e4Pba/

我还取消了alert调用,这是一种可恶的调试技术,如果您意外进入无限循环,可能会造成巨大的混乱,这样console.log更友好。

于 2013-06-10T21:53:48.733 回答