How to easily visualize both the i18n and AND attributes (using the Handlebars template) in Backbone.

Template rendering is a piece of cake when the data displayed in the template is either internationalized text or model attributes, but when it comes to rendering BOTH inside one template, I cannot find a clean solution.

For reference, I am using i18n through the Require.js i18n plugin.

Suppose I have a simple template:

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

The displayText object represents the text i18n, and the id element represents the attribute of the baseline model.

Using the Backbone template property in the view, I can do the following to render the template with i18n text, but without the 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, as soon as I want to display the model data as well, this no longer works, mainly due to this undefined in the template attribute (therefore, I cannot reference this.model.attributes ), and it seems that I should go back to overriding the method render() , passing both attributes of the i18n AND Model object to the template:

 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 would really like to leave Marionette by default to render() in place and use the template property only to display both i18n text and model data. Is it possible?

BONUS . Assuming I need to override render() , I notice that the this.ui attribute provided in Marionette Views no longer wraps each element as a jQuery object. It means that:

 this.ui.loadingNotification.show(); 

stops working by throwing Uncaught TypeError: Object #loading-load-data has no method 'show' . Why is this and how can I restore the correct functions of this.ui jQuery-wrapping?

EDIT : BONUS enabled; you just need to call this.bindUIElements() in the render() method to properly bind the elements to the ui hash. See the example above render() .

+4
source share
1 answer

SOLVED . So the answer is awkwardly simple. It turns out that you can pass the parameter to the template: property when used as a function, and this parameter represents the model associated with this view / template:

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

Now the render() method no longer needs to be overwritten, and both i18n text and model data can be displayed in the template as expected.

+2
source

All Articles