2012-04-25 43 views
2

我正在創建一個Web應用程序框架,供我部門的其他團隊使用,以標準化我們的Web應用程序的UI。它使用通過underscore.js的HTML模板以javascript編寫。然而,爲了使應用程序完全可擴展,我希望他們能夠在不修改源代碼的情況下擴展他們認爲合適的HTML模板。擴大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模板和複製/粘貼他們沒有修改的模板?

回答

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 S和嘗試從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 = { }; 

演示:http://jsfiddle.net/ambiguous/YpcJu/

+0

我真的很喜歡第二種解決方案 - 你認爲這會造成多大的性能損失? – stinkycheeseman 2012-04-25 18:55:51

+1

@stinkycheeseman:性能問題可能不會引起注意,但是您可以很輕鬆地緩存一些緩存(就像我的更新一樣)。 – 2012-04-25 19:31:36