我正在使用Backbone,因此我Underscore来渲染我的模板。我的模板在<script>
标签中呈现,然后我使用jQuery来获取他们的html。我的骨干视图如下所示:
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!')
}
})
我的问题是我只想为这个特定类型的视图只抓取一次html,这样如果我有很多项目,那么每次都不会在html中搜索此模板。< / p>
基本上我如何在ItemView
对象级别(不是视图的实例)正确存储模板变量,记住html的检索必须等到页面加载后(这样我才能保证)模板html可用。)
答案 0 :(得分:16)
您可以构建一个非常简单的对象来缓存模板:
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;
}
}
然后在您的视图中,您可以致电TemplateCache.get
并传入模板选择器。
Backbone.View.extend({
template: "#ItemTemplate",
render: function(){
var template = TemplateCache.get(this.template);
var html = template(this.model.toJSON());
this.$el.html(html);
}
});
第一次为给定的选择器调用TemplateCache.get
时,它将从DOM加载它。获取模板的任何后续调用都将从缓存版本加载它,并阻止额外的DOM访问调用。
FWIW:我在Backbone.Marionette框架中有一个更强大的TemplateCache
对象版本:https://github.com/derickbailey/backbone.marionette
答案 1 :(得分:5)
我见过的大多数Backbone示例都是这样做的。这只会在页面完成加载时遍历DOM一次以解析模板,并为每个new ItemView()
使用该模板。
App.ItemView = Backbone.View.extend({
template: _.template($("#ItemTemplate").html()),
className:'well',
events: {
'click .continue': 'handleContinueClick',
},
...
});
答案 2 :(得分:1)
您可以手动使用prototype.template
,并在第一次创建视图实例时编译模板。像这样:
initialize: function() {
if(!this.constructor.prototype.template)
this.constructor.prototype.template = _.template($("#ItemTemplate").html());
this.render();
}
演示:http://jsfiddle.net/ambiguous/e6y3F/
诀窍是让你的右手prototype
。
答案 3 :(得分:1)
您可以将已编译的模板存储在闭包中,以便只有ItemView的实例可以访问它:
(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!');
}
});
})();
答案 4 :(得分:1)
使用原型的另一种解决方案:
initialize: function(option) {
if (!this.template) App.ItemView.prototype.template = this.template || _.template($('ItemTemplate').html());
}
答案 5 :(得分:0)
您可以使用原始HTML代码,也可以从DOM-element获取应该在此脚本之前呈现的HTML代码
1)原始HTML代码:
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)或来自呈现DOM元素的HTML代码:
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;
}
});