如何组合来自不同HTML文件的模板

时间:2012-05-01 18:47:23

标签: knockout.js

由于Knockout的各个模板保存在脚本标记中,我认为我可以设置标记的src属性并从单独的文件加载HTML。如此天真地这样做是行不通的,所以要么

  1. 让模板绑定与我需要使用的src标签一起使用有一些技巧
  2. 从不同文件加载模板的方法不同
  3. (另外两种可能性 - 3,这个项目的所有程序员都希望修改相同的巨大文件,在启动时由浏览器加载,4,不要使用Knockoutjs来做任何更大的事情比玩具项目 - 我认为是等同的。)

2 个答案:

答案 0 :(得分:11)

对于任何类型不同于各种“javascript”类型之类的内容,浏览器不会响应src,并且会尝试将结果作为脚本执行。

但有几个选择:

答案 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文件的原因几乎相同。