admin管理员组文章数量:1190839
I'm using Backbone and therefore Underscore to render my templates. My templates get rendered in <script>
tags and then I use jQuery to grab their html. My backbone view looks like this:
App.ItemView = Backbone.View.extend({
className:'well',
events: {
'click .continue': 'handleContinueClick',
},
initialize: function() {
this.template = _.template($("#ItemTemplate").html())
this.render()
},
render: function() {
$(this.el).html(this.template({model:this.model}))
},
handleContinueClick: function(e) {
alert('Clicked!')
}
})
My Issue is I would like to only go and grab the html once and only once for this particular type of view so that if I have a lot of items it doesn't go searching the html for this template each time.
Basically how do I properly store the template variable at the ItemView
object level (not instance of the view) keeping in mind that the retrieval of the html has to wait until after page load (so that I can guarantee the template html is available).
I'm using Backbone and therefore Underscore to render my templates. My templates get rendered in <script>
tags and then I use jQuery to grab their html. My backbone view looks like this:
App.ItemView = Backbone.View.extend({
className:'well',
events: {
'click .continue': 'handleContinueClick',
},
initialize: function() {
this.template = _.template($("#ItemTemplate").html())
this.render()
},
render: function() {
$(this.el).html(this.template({model:this.model}))
},
handleContinueClick: function(e) {
alert('Clicked!')
}
})
My Issue is I would like to only go and grab the html once and only once for this particular type of view so that if I have a lot of items it doesn't go searching the html for this template each time.
Basically how do I properly store the template variable at the ItemView
object level (not instance of the view) keeping in mind that the retrieval of the html has to wait until after page load (so that I can guarantee the template html is available).
- Is there a reason you're worrying about this? I do hope you understand the evils of premature optimization. – JayC Commented Mar 23, 2012 at 2:29
- sure, if someone can tell me it doesn't matter, I'm cool with that. you're right it's prolly early, I'm just curious. – MattoTodd Commented Mar 23, 2012 at 2:31
- 1 @JayC - you're basically saying "DOM access for the same thing, multiple times, is premature optimization" which is pretty far from the truth. If the data never changes, only request it once. – Derick Bailey Commented Mar 23, 2012 at 2:36
- 3 @JayC - What does it matter why he's worrying about it? He may not even be working on a project at all, but is instead just simply trying to learn about best practices because he is interested. In either case if he wanted to know "when" to optimize I'm sure that's how the question would have been phrased. – apiguy Commented Mar 23, 2012 at 16:35
6 Answers
Reset to default 16You can build a very simple object that caches the templates for you:
TemplateCache = {
get: function(selector){
if (!this.templates){ this.templates = {}; }
var template = this.templates[selector];
if (!template){
var tmpl = $(selector).html();
template = _.template(tmpl);
this.templates[selector] = template;
}
return template;
}
}
Then in your view, you can call TemplateCache.get
and pass in your template selector.
Backbone.View.extend({
template: "#ItemTemplate",
render: function(){
var template = TemplateCache.get(this.template);
var html = template(this.model.toJSON());
this.$el.html(html);
}
});
The first time you call TemplateCache.get
for a given selector, it will load it from the DOM. Any subsequent calls to get the template will load it from the cached version and prevent the extra DOM access call.
FWIW: I have a much more robust version of the TemplateCache
object in my Backbone.Marionette framework: https://github.com/derickbailey/backbone.marionette
Most Backbone examples I've seen do it like this. This will only traverse the DOM once to parse the template when the page finishes loading and use that for each new ItemView()
.
App.ItemView = Backbone.View.extend({
template: _.template($("#ItemTemplate").html()),
className:'well',
events: {
'click .continue': 'handleContinueClick',
},
...
});
http://backbonejs.org/docs/todos.html#section-21
You could muck around with prototype.template
by hand and compile the template the first time you create an instance of your view. Something like this:
initialize: function() {
if(!this.constructor.prototype.template)
this.constructor.prototype.template = _.template($("#ItemTemplate").html());
this.render();
}
Demo: http://jsfiddle.net/ambiguous/e6y3F/
The trick is to get your hands on the right prototype
.
You could store the compiled template in a closure so that only the instances of ItemView can access it:
(function() {
var template;
App.ItemView = Backbone.View.extend({
className:'well',
events: {
'click .continue': 'handleContinueClick'
},
initialize: function() {
this.render();
},
render: function() {
template = template || _.template($("#ItemTemplate").html());
$(this.el).html(template({model:this.model}));
},
handleContinueClick: function(e) {
alert('Clicked!');
}
});
})();
Another solution using prototype:
initialize: function(option) {
if (!this.template) App.ItemView.prototype.template = this.template || _.template($('ItemTemplate').html());
}
You could use raw HTML-code or you might get HTML-code from DOM-element which should had rendered before this script
1) raw HTML-code:
var app = app || {};
app.TreeView = Backbone.View.extend({
tagName: 'ul',
id: 'js-tree',
template: _.template('<li data-id="<%- id %>"><%- Name %></li>'),
initialize: function() {
this.render();
},
render: function () {
this.model.each(this.renderRow, this);
return this;
},
renderRow: function(model) {
var html = template(model);
this.$el.append(html);
return this;
}
});
2) or HTML-code from rendered DOM-element:
var app = app || {};
app.TreeView = Backbone.View.extend({
tagName: 'ul',
id: 'js-tree',
template: _.template($("#js-template-tree-item").html()),
initialize: function() {
this.render();
},
render: function () {
this.model.each(this.renderRow, this);
return this;
},
renderRow: function(model) {
var html = template(model);
this.$el.append(html);
return this;
}
});
本文标签:
版权声明:本文标题:backbone.js - How do I properly store a javascript template, so that it isn't instantiated multiple times - Stack Overfl 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738438149a2086799.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论