Я пытаюсь передать шаблон своему представлению. У меня есть несколько разных шаблонов, которые я хочу использовать, и хочу иметь возможность переключать их в моем маршрутизаторе. Я не получаю ошибок, но не получаю результатов. Похоже, что во втором представлении метод initialize не вызывается. Вот мой код:

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

        window.template = function(id) {
            return _.template( $('#' + id).html() );
        };

        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 = new (App.Views.Tables.extend({
     collection: t, template: 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, template: template});
                this.$el.append(t.render().el);
                return this;
            }
        });

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



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

РЕДАКТИРОВАТЬ: мне не хватало скобок. Но теперь я получаю ошибку нераспознанного выражения. Вызывается инициализация.

1
sehummel 8 Янв 2013 в 21:43

1 ответ

Лучший ответ

То, как вы это делаете в App.Views.Table, является (насколько я могу судить) "стандартным" способом использования шаблонов в Backbone. Однако, конечно, есть несколько альтернатив, и ни одна из них не является «неправильной».

При этом у вас есть пара проблем в вашем коде. Давайте начнем с:

template: this.template,

Во время выполнения кода вы не находитесь в экземпляре App.Views.Tables, а находитесь в глобальном пространстве, объявляя класс, который (позже) будет использоваться для создания экземпляров. Однако в тот момент this относится только к window. Что вы действительно хотите сделать, так это установить шаблон в своем initialize, что приводит меня к следующему:

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

Но есть еще одна проблема:

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

В этой функции нет переменной шаблона, так что вы действительно делаете template: undefined. Это должен использовать настоящий шаблон.

С учетом всего вышесказанного вы можете просто рассмотреть возможность размещения шаблона непосредственно в представлении, как вы вроде пытались:

template: Handlebars.compile('<span>{{test}}</span>'),

В конце концов, любое представление всегда должно использовать один и тот же шаблон, верно? Кроме того, вы можете подумать о перемещении:

render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    return this;
}

В родительский класс, чтобы вы могли делиться им между всеми вашими шаблонными представлениями, вместо того, чтобы повторять его.

3
machineghost 18 Июл 2015 в 01:32
Не все мои взгляды будут использовать один и тот же шаблон. Я пытаюсь динамически переключать шаблоны.
 – 
sehummel
8 Янв 2013 в 22:02
Кроме того, похоже, вы лишили меня возможности динамически переключать URL-адрес. Я пытаюсь написать код, который позволит мне переключать шаблоны и URL-адреса в маршрутизаторе. Я пытаюсь избежать дублирования кода. Эти две вещи - единственные различия в том, что мне нужно делать несколько раз для каждого маршрута.
 – 
sehummel
8 Янв 2013 в 22:05
Верно, но вы можете поместить разные шаблоны в каждое представление. Вы можете: var View1 = Backbone.View.extend({template: template1}); var View2 = Backbone.View.extend({template: template2});
 – 
machineghost
8 Янв 2013 в 22:05
Понятия не имею, о чем вы говорите, говоря о «переключении URL-адреса»; упомянутый мной код не имеет ничего общего с маршрутизатором. Возможно, вы не понимаете, как соединяются представления / маршрутизаторы / URL-адреса?
 – 
machineghost
8 Янв 2013 в 22:06
В этой строке t = new (App.Collections.Tables.extend({ url: 'send-message'}))(); я передаю URL-адрес, который зависит от маршрута.
 – 
sehummel
8 Янв 2013 в 22:07