Reputation:
Rendering templates is a piece of cake when the data displayed within the template is either internationalized text OR model attributes, but when it comes to rendering BOTH within one template, I can't seem to find a clean solution.
For reference, I'm utilizing i18n via Require.js's i18n plugin.
Let's assume I have a simple template:
<h3>{{displayText.load}} #{{id}}</h3>
<h4 id="loading-load-data">{{displayText.loadingLoadData}}...</h4>
The displayText
object represents i18n text, while the id
item represents a Backbone Model attribute.
Using Backbone's template
property on a View, I can do the following in order to render a template with i18n text, but without Model attribute data:
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
});
However, once I want to also display the Model data, this no longer works, primarily due to this
being undefined within the template attribute (so I can't reference this.model.attributes
), and it seems that I have to fall back to overriding the render()
method, passing both the i18n object AND Model attributes to the template, as such:
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;
}
});
I'd really love to leave Marionette's default handling of render()
in place, and solely use the template property to render both i18n text AND the Model data. Is this possible?
BONUS: Assuming I DO have to override render()
, I'm noticing that while doing so, the this.ui
attribute, provided on Marionette Views, no longer wraps each item as a jQuery object. This means that:
this.ui.loadingNotification.show();
stops functioning, throwing an Uncaught TypeError: Object #loading-load-data has no method 'show'
. Why is this, and how can I restore proper this.ui
jQuery-wrapping functionality?
EDIT: Solved the BONUS; simply have to toss in a this.bindUIElements()
call within the render()
method to properly bind the elements to the ui
hash. See the render()
example above.
Upvotes: 4
Views: 1351
Reputation:
SOLVED: So the answer is embarrassingly simple. Turns out you can pass a parameter into the template: property when used as a function, and this parameter represents the Model associated with that View/template:
template: function (model) {
var templateParams = _.extend({}, model, localizedText),
renderedTemplate = Handlebars.compileClean(template);
return renderedTemplate(templateParams);
},
The render()
method then no longer needs to be overwritten, and both i18n text and Model data can be rendered into the template as expected.
Upvotes: 2