如何正确存储javascript模板,使其不会;t实例化了多次
How do I properly store a javascript template, so that it isn't instantiated multiple times
我使用Backbone,因此使用Undercore来渲染我的模板。我的模板在<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中搜索这个模板。
基本上,我如何在ItemView
对象级别(而不是视图的实例)正确存储模板变量,记住html的检索必须等到页面加载之后(这样我才能保证模板html可用)。
您可以构建一个非常简单的对象来缓存模板:
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
我见过的大多数骨干示例都是这样做的。这将只遍历DOM一次,以便在页面完成加载时解析模板,并将其用于每个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
您可以手动处理prototype.template
,并在第一次创建视图实例时编译模板。类似这样的东西:
initialize: function() {
if(!this.constructor.prototype.template)
this.constructor.prototype.template = _.template($("#ItemTemplate").html());
this.render();
}
演示:http://jsfiddle.net/ambiguous/e6y3F/
诀窍是拿到正确的prototype
。
您可以将编译后的模板存储在闭包中,这样只有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!');
}
});
})();
另一个使用原型的解决方案:
initialize: function(option) {
if (!this.template) App.ItemView.prototype.template = this.template || _.template($('ItemTemplate').html());
}
您可以使用原始HTML代码,也可以从DOM元素中获取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;
}
});
- 如何在GoogleWeb工具包(GWT)中从JSNI调用接口(实例化)
- 如何在用户输入时实例化数组
- 在requirejs中共享实例化对象
- Mongoose TypeError:实例化模式类型的对象时,对象不是函数
- Angular重命名模块后未能实例化模块
- Backbone relational无法实例化两个RelationalModel对象
- 我应该如何用javascript实例化这个日期
- AngularJS出错-无法实例化模块
- 谷歌地图重叠MarkerSpiderfier实例化问题
- 未捕获错误:由于,[$injector:moduler]未能实例化模块polmgr
- ngRoute不是因果报应实例化的
- JavaScript 中的动态实例化
- 在文本框上绑定谷歌地点自动完成,而无需实例化谷歌地图
- UI5 路由不实例化视图
- 在 JavaScript 中,当我们实例化派生对象时,原型的函数隐藏在哪里
- 存储对通讯簿应用的实例化对象的引用
- 如何正确存储javascript模板,使其不会;t实例化了多次
- 实例化对象,而不是将它们存储在变量中
- 是否可以在jQuery/Javascript中存储非实例化对象的信息?
- 将ES6类存储在变量中,并通过Object.Create实例化