Как проще всего визуализировать как текст i18n, так и атрибуты модели (используя шаблон Handlebars) в Backbone.Marionette View

Рендеринг шаблонов — это пустяк, когда данные, отображаемые в шаблоне, представляют собой интернационализированный текст ИЛИ атрибуты модели, но когда дело доходит до рендеринга ОБА в одном шаблоне, я не могу найти четкого решения.

Для справки, я использую i18n через плагин i18n Require.js.

Предположим, у меня есть простой шаблон:

<h3>{{displayText.load}} #{{id}}</h3>

<h4 id="loading-load-data">{{displayText.loadingLoadData}}...</h4>

Объект displayText представляет текст i18n, а элемент id представляет атрибут модели магистрали.

Используя свойство Backbone template в представлении, я могу сделать следующее, чтобы отобразить шаблон с текстом i18n, но без данных атрибута модели:

return Backbone.Marionette.ItemView.extend({
    template: function () {
        var compiledTemplate = Handlebars.compileClean(template);

        // localizedText represents the i18n localization object, using the Require.js i18n plugin
        return compiledTemplate(localizedText);
    },
    // some more View properties and methods
});

Однако, как только я хочу также отображать данные модели, это больше не работает, в основном из-за того, что this не определено в атрибуте шаблона (поэтому я не могу ссылаться на this.model.attributes), и кажется, что мне нужно вернуться к переопределению render() метод, передавая как объект i18n, так и атрибуты модели в шаблон, как таковой:

return Backbone.Marionette.ItemView.extend({
    template: Handlebars.compileClean(template),
    render: function() {
        var templateParams = _.extend({}, this.model.attributes, localizedText),
            renderedTemplate = this.template(templateParams);

        this.$el.html(renderedTemplate);

        this.bindUIElements();
        this.delegateEvents();

        return this;
    }
});

Мне бы очень хотелось оставить стандартную обработку Marionette render() на месте и использовать исключительно свойство шаблона для отображения как текста i18n, так и данных модели. Это возможно?

БОНУС: если предположить, что мне ДЕЙСТВИТЕЛЬНО нужно переопределить render(), я замечаю, что при этом атрибут this.ui, предоставляемый в Marionette Views, больше не оборачивает каждый элемент как объект jQuery. Это означает, что:

this.ui.loadingNotification.show();

перестает функционировать, выдавая Uncaught TypeError: Object #loading-load-data has no method 'show'. Почему это так и как я могу восстановить правильную функциональность this.ui jQuery-обертки?

РЕДАКТИРОВАНИЕ: Решена проблема БОНУС; просто нужно добавить вызов this.bindUIElements() в метод render(), чтобы правильно связать элементы с хешем ui. См. пример render() выше.


person J. Ky Marsh    schedule 04.12.2012    source источник


Ответы (1)


РЕШЕНО. Итак, ответ до безобразия прост. Оказывается, вы можете передать параметр в свойство template: при использовании в качестве функции, и этот параметр представляет модель, связанную с этим представлением/шаблоном:

template: function (model) {
    var templateParams = _.extend({}, model, localizedText),
        renderedTemplate = Handlebars.compileClean(template);

    return renderedTemplate(templateParams);
},

После этого метод render() больше не нужно перезаписывать, и как текст i18n, так и данные модели могут быть отображены в шаблоне, как и ожидалось.

person J. Ky Marsh    schedule 05.12.2012