我正在创建一个Web应用程序框架,供我部门中的其他组使用,以标准化我们的Web应用程序的UI。它是用javascript编写的,使用HTML模板通过underscore.js。但是为了让应用程序完全可扩展,我希望他们能够在不修改源代码的情况下扩展HTML模板。
来源
templates.html
...
<script type="text/template" id="fooTemplate">
<div class="foo">
</div>
</script>
<script type="text/template" id="barTemplate">
<p>Bar!</p>
</script>
...
实施
newTemplates.html
...
<!-- Only overwrite foo, not bar !-->
<script type="text/template" id="fooTemplate">
<ul class="foo">
<li class="bar">Blah!</li>
</ul>
</script>
...
有没有办法直观地让用户扩展HTML模板而不强制他们覆盖文件并复制/粘贴他们没有修改的模板?
答案 0 :(得分:1)
如果没有一堆服务器端处理来处理唯一性问题,您将无法使用id
属性来识别模板。但您可以使用类来识别模板。
如果您将所有模板HTML文件按覆盖顺序混合在一起(首先是“基本”模板,之后是“子模板”),并使用class
属性来识别模板:
<!-- templates.html -->
<script type="text/template" id="fooTemplate">
<div class="foo">
</div>
</script>
<script type="text/template" id="barTemplate">
<p>Bar!</p>
</script>
<!-- newTemplates.html -->
<script type="text/template" id="fooTemplate">
<ul class="foo">
<li class="bar">Blah!</li>
</ul>
</script>
然后你可以使用像
这样的东西var foo = _.template($('.fooTemplate:last').html());
var bar = _.template($('.barTemplate:last').html());
访问您的模板。
演示:http://jsfiddle.net/ambiguous/gYHkF/
您还可以坚持使用id
并尝试从newTemplates.html
首先加载模板,如果找不到,则尝试回退到templates.html
。如果您将模板文件加载到两个单独的变量中,但不将它们插入DOM :
var $base = $('stuff from templates.html');
var $subs = $('stuff from newTemplates.html');
然后在$subs
之前添加一个简单的函数来查找$base
中的模板:
function tmpl(id) {
var $t = $subs.filter('#' + id);
if($t.length)
return _.template($t.html());
return _.template($base.filter('#' + id).html());
}
然后你可以这样做:
var foo = tmpl('fooTemplate');
var bar = tmpl('barTemplate');
并且正确的事情会发生。
演示:http://jsfiddle.net/ambiguous/EhhsL/
这种方法也可以很容易地缓存已编译的模板,不仅可以避免双重查找,还可以避免反复编译相同的内容:
function tmpl(id) {
if(tmpl.cache.hasOwnProperty(id))
return tmpl.cache[id];
var $t = $subs.filter('#' + id);
if($t.length)
return tmpl.cache[id] = _.template($t.html());
return tmpl.cache[id] = _.template($base.filter('#' + id).html());
}
tmpl.cache = { };