2013-01-16 47 views
0

我正在嘗試編寫一個Grails自定義標記(其中包括)觸發包含資源,因此類似<myTags:view name="foo"/>會加載比如說js/views/foo.js 。我想要它與disposition: 'head'加載。從Grails自定義標籤加載靜態資源,處置:'head'

我可以使用<r:external/>,但不會將它放在<head>中,它只會產生一個內嵌<script/>標記。我可以使用<r.script/>,但這不會讓我引用一條路徑;我必須讓我的自定義標籤讀取文件並將其轉儲到out

現在,如果foo.js是它自己的模塊,我可以這樣做:r.require([module: 'foo']),但它不是;這一點的一部分是我不想在ApplicationResources.groovy中聲明所有這些文件。但是,也許我可以通過閱讀可用文件以編程方式創建模塊 - 這可能嗎?或者,還有更好的方法?

+1

真的重點是創建模塊,並將它們包含在需要它們的頁面中。我明白你想要做什麼,但我認爲它不會在實踐中發揮作用。如果您多次使用標籤,可能會多次加載該文件。如果你遵循Grails約定,你會變得更好。 –

+0

我從經驗中知道,如果我要求開發人員每次創建一個視圖以在ApplicationResources.groovy中創建一個模塊條目,並且每次他們使用視圖以確保存在標記時,他們都會忘記,我們會一遍又一遍地重複同樣的問題。我寧願不違反幹。 –

+0

嗯,它看起來像實際上 *是應該把它放在頭上,但據我所知,它什麼都不做。 –

回答

0

我最終以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> 

這不是很漂亮,但混亂主要是隱藏的,它應該大大降低樣板和忘記添加魔術字符串到多個文件的機會。