我最終以ApplicationResources.groovy
以編程方式創建模塊,因此自定義標記可以使用<r:require/>
。
的想法是,對於每一個骨幹視圖,web-app/myApp/views
下,有一個.js
文件中的骨幹視圖,並在.handlebars
文件把手模板(名稱相同,按照約定)。 .handlebars
文件被聲明爲普通模塊,但被Handlebars-Resources插件預編譯。
在ApplicationResources.groovy
一些代碼發現所有的視圖,並創建對應的資源的模塊:
GrailsApplication grailsApplication = Holders.getGrailsApplication()
File viewsDir = grailsApplication.parentContext.getResource("myApp/views").file;
if (viewsDir.exists() && viewsDir.isDirectory() && viewsDir.canRead()) {
String[] viewsJS = viewsDir.list().findAll { name ->
name.endsWith("View.js")
}
String[] views = viewsJS.collect { name ->
name.substring(0, name.length() - ".js".length())
}
for (view in views) {
"${view}" {
dependsOn 'backbone', 'backbone_relational', 'handlebars'
resource url: "dpg/views/${view}.handlebars",
attrs: [type: 'js'],
disposition: 'head'
resource url: "dpg/views/${view}.js",
disposition: 'head'
}
}
}
然後,標記庫:
class ViewsTagLib {
static namespace = "myApp"
def view = { attrs ->
r.require(module: "${attrs.name}View")
out << "<${attrs.tagName} id='${attrs.id}'></${attrs.tagName}>"
}
}
在GSP調用它:
<myApp:view tagName="div" name="foo" id="foo1"/>
<myApp:view tagName="div" name="foo" id="foo2"/>
可生產:
<html>
<head>
...
<!--
Automagically generated modules (included only once).
Should put these in the same bundle, but handlebars-resources
gets confused.
-->
<script src="/myApp/static/bundle-bundle_fooView_handlebars.js"
type="text/javascript" ></script>
<script src="/myApp/static/bundle-bundle_fooView_head.js"
type="text/javascript" ></script>
</head>
<body>
...
<div id="foo1"></div> <!-- backbone placeholder for 1st view instance-->
<div id="foo2"></div> <!-- backbone placeholder for 2nd view instance-->
</body>
</html>
這不是很漂亮,但混亂主要是隱藏的,它應該大大降低樣板和忘記添加魔術字符串到多個文件的機會。
真的重點是創建模塊,並將它們包含在需要它們的頁面中。我明白你想要做什麼,但我認爲它不會在實踐中發揮作用。如果您多次使用標籤,可能會多次加載該文件。如果你遵循Grails約定,你會變得更好。 –
我從經驗中知道,如果我要求開發人員每次創建一個視圖以在ApplicationResources.groovy中創建一個模塊條目,並且每次他們使用視圖以確保存在 標記時,他們都會忘記,我們會一遍又一遍地重複同樣的問題。我寧願不違反幹。 –
嗯,它看起來像實際上 *是應該把它放在頭上,但據我所知,它什麼都不做。 –