由于Knockout的各个模板保存在脚本标记中,我认为我可以设置标记的src
属性并从单独的文件加载HTML。如此天真地这样做是行不通的,所以要么
src
标签一起使用有一些技巧(另外两种可能性 - 3,这个项目的所有程序员都希望修改相同的巨大文件,在启动时由浏览器加载,4,不要使用Knockoutjs来做任何更大的事情比玩具项目 - 我认为是等同的。)
答案 0 :(得分:11)
对于任何类型不同于各种“javascript”类型之类的内容,浏览器不会响应src
,并且会尝试将结果作为脚本执行。
但有几个选择:
循环包含模板的脚本标记并加载它们。这样的事情会使用src
作为位置来提取内容。如果您的模板尚未就绪,则在调用applyBindings时需要注意。
$("script[type='text/html']").each(function(index, el) { $.get($(el).attr("src"),
function(response) {
$(el).text(response); });
});
以下是我在一段时间内所做的一些其他选项:http://www.knockmeout.net/2011/03/using-external-jquery-template-files.html
答案 1 :(得分:1)
我项目中的每个模板都是自己的html文件。我使用命名约定(* .ko.html)来识别它们。 我的构建链是这样的:
第1步:Lint并缩小* .ko.html文件
这只是为了删除注释(<!-- ko -->
除外)并删除额外的空格以获得更紧凑的有效负载。
第2步:将缩小的html字符串化并连接到js文件中。 js看起来像
var templates={
'name1':'some stringified html',
'name2':'some more'
};
我确实考虑使用<script type="text/plain">
分隔符连接到html文件,但选择了js,因为这样可以使用简单的<script>
标记而不是ajax get + inject加载。
步骤3:修复本机模板引擎以从我的js对象中检索模板。
var engine = new ko.nativeTemplateEngine();
engine._makeTemplateSource = engine.makeTemplateSource;
engine.makeTemplateSource = function (template, doc) {
if (typeof (template) === 'string' && templates[template]) {
return { text: function () { return templates[template]; } };
}
return engine._makeTemplateSource(template, doc);
};
ko.setTemplateEngine(engine);
我的实现使用gruntjs来执行这些构建步骤。 (grunt-contrib-htmlmin,grunt-contrib-concat)
htmlmin的选项:
{
removeComments: true,
collapseWhitespace: true,
ignoreCustomComments: [/^\s*ko /, /^\s*\/ko /]
}
concat的选项
{
stripBanners: true,
banner: "(function(t){",
footer: "})(window.templates || (window.templates={}));",
process: function (src, file) {
return 't[\'' + file.replace(/^.*\//, '').replace('.ko.html', '') + '\']=' + JSON.stringify(src) + ';';
}
}
对于任何想知道为什么有人想要这样做的人:
模板源文件是标准的单个html文件,可以在任何html编辑器中编辑,并且源控制如此。在<script>
标签内编辑html并不好玩。作为奖励,源文件可以包含将被删除的注释。
通过包含脚本标记,模板可以在任何页面上重复使用:不需要在每个页面中内嵌它们。
生成的包是一个静态文件,浏览器可以轻松缓存,而嵌入到动态生成的页面中的模板不能。
捆绑javascript文件的原因几乎相同。