骨干视图不会渲染传递给它的模板

时间:2013-01-08 21:23:05

标签: backbone.js backbone-views

我需要能够将不同的模板ID传递给不同的路由。

(function() {
    window.App = {
        Models: {},
        Collections: {},
        Views: {},
        Router: {}
    };

    var vent = _.extend({}, Backbone.Events);

    _.templateSettings.interpolate = /\[\[(.+?)\]\]/g;

    App.Router = Backbone.Router.extend({
        routes: {
            '' : 'index',
            'send-message' : 'sendMessage',
            '*other' : 'other'
        },
        index: function() {
            t = new (App.Collections.Tables.extend({ url: 'main-contact'}))();
            tables = App.Views.Tables({ collection: t, template: 'mainContactTemplate' });
            $('#web-leads').html(tables.el);
        },
        sendMessage: function() {
            // t = new (App.Collections.Tables.extend({ url: 'send-message'}))();
            // tables = new App.Views.Tables.extend({ collection: t, template: template('sendMessageTemplate')});
            // $('#web-leads').html(tables.el);
        },
        other: function() {

        }
    });

    // Main Contact
    App.Models.Table = Backbone.Model.extend({});

    App.Collections.Tables = Backbone.Collection.extend({
        model: App.Models.Table,
        initialize: function(models, options) {
            this.fetch({
                success: function(data) {
                    //console.log(data.models);
                }
            });
            if (options) {
                this.url = this.url || options.url;
            }
        }
    });

    App.Views.Tables = Backbone.View.extend({
        tagName: 'ul',
        initialize: function() {
            this.collection.on('reset', this.render, this);
        },
        render: function() {
            return this.collection.each(this.addOne, this);
        },
        addOne: function(model) {
            var t = new App.Views.Table({ model: model});
            this.$el.append(t.render().el);
            return this;
        }
    });

    App.Views.Table = Backbone.View.extend({
        tagName: 'li',
        initialize: function(options) {
            this.template = options.template;
            console.log(this.options);
        },
        retrieveTemplate: function(model) {
            return _.template($('#' + this.template).html(), model);
        },
        render: function() {
            this.$el.html(this.retrieveTemplate(this.model.toJSON()));
            return this;
        }
    });

    new App.Router();
    Backbone.history.start();
})();

但我得到的错误不是n is undefined。我想我需要将this.template传递给我的retrieveTemplate函数。但它不应该已经设置好了吗?顺便说一下,如果我在retrieveTemplate函数中对模板ID的名称进行硬编码,则此代码可以正常工作。

编辑:模板未从路由器中的呼叫传递。这就是崩溃的地方。

编辑:我取消了在索引路线的第二行延伸的调用,现在我得到了this._configure is not a function

工作版本:

(function() {
    window.App = {
        Models: {},
        Collections: {},
        Views: {},
        Router: {}
    };

    var vent = _.extend({}, Backbone.Events);

    _.templateSettings.interpolate = /\[\[(.+?)\]\]/g;

    App.Router = Backbone.Router.extend({
        routes: {
            '' : 'index',
            'send-message' : 'sendMessage',
            '*other' : 'other'
        },
        index: function() {
            var t = new (App.Collections.Tables.extend({ url: 'main-contact'}))();
            var tables = new (App.Views.Tables.extend({ collection: t, options: {template: 'mainContactTemplate' }}))();
            $('#web-leads').html(tables.render().el);
        },
        sendMessage: function() {
            // t = new (App.Collections.Tables.extend({ url: 'send-message'}))();
            // tables = new App.Views.Tables.extend({ collection: t, template: template('sendMessageTemplate')});
            // $('#web-leads').html(tables.el);
        },
        other: function() {

        }
    });

    // Main Contact
    App.Models.Table = Backbone.Model.extend({});

    App.Collections.Tables = Backbone.Collection.extend({
        model: App.Models.Table,
        initialize: function(models, options) {
            this.fetch({
                success: function(data) {
                    //console.log(data.models);
                }
            });
            if (options) {
                this.url = this.url || options.url;
            }
        }
    });

    App.Views.Tables = Backbone.View.extend({
        tagName: 'ul',
        initialize: function(options) {
            this.collection.on('reset', this.render, this);
            this.template = this.options.template;
        },
        render: function() {
            this.collection.each(this.addOne, this);
            return this;
        },
        addOne: function(model, options) {
            //console.log(model);
            var t = new App.Views.Table({ model: model, template: this.options.template});
            this.$el.append(t.render().el);
            return this;
        }
    });

    App.Views.Table = Backbone.View.extend({
        tagName: 'li',
        initialize: function(options) {
            //console.log(this.options);
            this.template = this.options.template;
        },
        retrieveTemplate: function(model) {
            return _.template($('#' + this.template).html(), model);
        },
        render: function() {
            //console.log(this);
            this.$el.html(this.retrieveTemplate(this.model.toJSON()));
            return this;
        }
    });

    new App.Router();
    Backbone.history.start();
})();

2 个答案:

答案 0 :(得分:1)

您可能需要绑定上下文。 Underscore可以帮助你。

.bindAll .bind应该这样做。

我通常只在初始化期间使用_.bindAll,如下所示。

...
initialize: function(options) {
    _.bindAll(this); // apply appropriate context
    this.template = options.template;
},
...

希望这有帮助,祝你好运。

答案 1 :(得分:1)

您的路由器说:

tables = App.Views.Tables({ collection: t, template: 'mainContactTemplate' });

所以你给template: '...' App.Views.Tablesinitialize中的App.Views.Tables如下所示:

initialize: function() {
    this.collection.on('reset', this.render, this);
}

因此它会忽略template选项。如果我们查看App.Views.Table(单数!),我们会看到:

initialize: function(options) {
    this.template = options.template;
    console.log(this.options);
}

App.Views.Table实例化时没有template选项:

var t = new App.Views.Table({ model: model});

您需要修复使用App.Views.Table的方式。 Backbone会放一个view's constructor options in this.options for you所以你只需要说:

var t = new App.Views.Table({ model: model, template: this.options.template });

还需要考虑其他一些事项:

  1. 路由器的index方法中有一些偶然的全局变量,你应该var tvar tables而不只是ttables
  2. 视图的render方法通常会返回this,因此您可以说$x.append(v.render().el),因此您可能需要调整render方法以符合约定。