每次使用模板时都要编译它们
Compiling templates every time I use them
我使用Backbone、Requirejs和Handlebars来管理我的前端结构。然而,我遇到了一个颠簸。考虑以下片段:
render: function() {
var template = Handlebars.compile(TestViewTemplate);
var srchtml = template({
test: 'hello'
});
this.$el.html(srchtml);
}
假设此视图在网站中多次渲染,并多次执行渲染功能。调用.compile方法会导致每次都需要"重新编译"视图的开销吗?还是Handlebars每次编译时都会保存模板的缓存副本?我是否应该将Context对象传递给我的所有View模块,在那里我保存编译的模板,并检查模板是否已经编译,如果已经编译,请使用已经编译的模板并渲染它?
有标准的方法来处理这个问题吗?
我对Handlebars真的很新鲜,任何建议都非常感谢!
这不是你想要的完整答案,但对于评论来说有点太多了-虽然没有完全消除开销,但在创建视图时,我的常规方法是声明一个属性模板,即编译后的模板。这样,它只会在创建时进行编译。
var ModelView = Backbone.View.extend({
//get the template and cache it for future use
template: Handlebars.compile(templateName),
initialize: function() {
},
//render this view with the models data
render: function() {
//attach the generated template to this views $el
this.$el.html(this.template(this.model.toJSON()));
return this;
},
});
重新呈现同一视图时,该视图已引用了已编译的模板。但这并不能掩盖这样一个事实,即这种类型的每个新视图都将编译
所以我找到了一个更持久的解决方案,并希望与其他人分享我的做法。
我创建了一个Context对象,它只实例化一次,并在整个应用程序中传递。这就是它的样子:
define([
'jquery',
'handlebars'
], function($, Handlebars) {
this.ctx = this.ctx || new function(options) {
if( typeof options === 'undefined' ) options = {};
/**
* introducing a _this variable that holds scope to the base object.
*/
var _this = this;
/**
* Keeps track of whether the Context has been initialized or not,
* prevents double initialization.
*/
var initialized = false;
var initHelpers = function() {
Handlebars.registerHelper('ifeq', function(v1, v2, options) {
return (v1 === v2) ? options.fn(this) : options.inverse(this);
});
}
this.init = function(options) {
if( initialized ) {
console.log('Prevented an attempt at initializing the Context object twice.');
return;
}
/* Setting the debug variable, look at the declaration above in the implementation
* for more information about this. */
debug = options.debug || false;
/**
* Initializing the Handlebars helpers, necessary for the template rendering.
*/
initHelpers();
}
// Functionality for the template caching methods. //
var hbsTemplates = {};
this.getTemplate = function(name, templateHtml) {
return hbsTemplates[name] || function() {
var compiledTemplate = Handlebars.compile(templateHtml);
hbsTemplates[name] = compiledTemplate;
return compiledTemplate;
}();
}
}
return this.ctx;
});
我们还必须启动它,最好是尽快启动。
Context.init({
/* Options */
});
当我创建主干视图时,我声明以下变量:
template: Context.getTemplate('mywidget.mytemplate', FloorViewTemplate),
请注意作为第一个参数传递的字符串。这是用来引用Context对象中HashMap中的模板的,我用文件夹结构来表示。在这种情况下,它是mywidget/mytemplate.hbs,表示为mywidget.mytemplate
记住,在这一点上,Context对象已经作为任何其他类型的被提取
define([
'Context'
], function(Context) {
});
最后,我们得到模板并提供我们的参数。
var html = this.template({
arg1: 1,
arg2: 2
});
现在只需要将html添加到DOM中。
这很好用。如果有人对如何更有效地做到这一点有任何其他想法,请编辑答案。
- AngularJS指令出错-无法读取属性'编译'的未定义
- 如何使用ViewCompiler手动编译DOM的一部分
- 预编译的车把模板使文件大小加倍
- Mocha react本地路由器编译错误
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 在编译阶段后创建新的DOM树,或者继续使用原始修改的DOM
- 如何在Windows中将Javascript文件编译成二进制文件
- 浏览器是否持久缓存脚本元素的编译版本
- GWT:有没有一种方法可以修改GWT在编译中使用的Cast.java文件
- 使用脚本#编译代码(独立)
- 是否可以使用有角度的HTML文档进行$编译
- 使用Gulp手柄部分编译为单个HTML文件
- AngularJS:带有HTML和angular表达式的指令;编译”;具有外部范围的内容
- Javascript赢得'不能在IE上编译,但可以在Chrome上运行
- Bootstrap CSS和JS我必须将它们包含在单独的文件中,或者可以编译它们
- 在 ng-if 编译后访问指令中的 DOM 元素
- 当单元格内容由于forumula从另一个工作表编译数据而更改时发送电子邮件
- ScriptEngineManager能给我它刚刚用Java编译的Javascript函数的名称吗
- 我的所有代码在使用Webpack编译时都会运行两次
- Grunt PostCSS编译非常慢