2010-11-17 37 views
8

我目前正在重組Play!項目,在HTML模板文件中有很多JS 代碼。此代碼應移至外部的 JS文件,以獲得更好的可讀性和更快的頁面加載時間。但是,當我在公用文件夾中創建一個JS文件時,所有 @ {Controller.method}鏈接替換都不再有效。我 想調用一些初始化函數從HTML 模板,只是提供所需的URL像玩!框架:在單獨的JavaScript文件中使用URL的最佳實踐?

initialize({ "Application.doThis" : "@{Application.doThis}"}) 

然而這變得非常繁瑣,容易出錯的與被添加任何URL 。另一件事是,I18N也不再有效。所以 對於這樣的場景,最佳做法是什麼?您的 JS代碼位於單獨的文件中,但仍希望在您的JS中使用URL生成和 I18N?

回答

12

在主模板,生成 '的Javascript路由器',是這樣的:

<script> 
    var routes = { 
     doThis: #{jsAction @Application.doThis(user, ':param1', ':param2') /}, 
     doThat: #{jsAction @doThat() /} 
    } 
</script> 

然後在任何 '靜態' 的JavaScript文件,使用該路由器:

$.get(routes.doThis({param1: x, param2: 'yop'})) 
+1

謝謝。這正是我想到的,然而這實際上意味着我需要很多樣板代碼,我必須在每當出現一條新路線時進行擴展,這很容易被遺忘。另一件事是使用i18n處理JavaScript內部的消息,當然也可以爲消息編寫這樣一個「路由器」,但這樣可以有效地複製JavaScript中的所有I18N密鑰。 – 2010-11-18 14:05:40

+0

您已經可以使用#{18n /}標籤。我想我們可以提供一個標籤,通過JavaScript公開整個路徑文件,但它可能會導致安全問題。 – 2010-11-18 15:32:56

+0

好的,非常感謝! – 2010-11-18 18:55:40

5

的訣竅是獲取框架來解析你的javascript,或者你的CSS,或者靜態目錄中的其他東西。這是一個簡單的解決方案。

添加controllers.StaticParser控制器:

package controllers; 
import play.mvc.Controller; 

public class StaticParser extends Controller { 
    public static void parse(String route) { 
     render("/" + route); 
    } 
} 

要將conf/routes文件中加入:

GET /parse/{<.*>route} StaticParser.parse 

在該路線的正則表達式是非常重要的,否則你不能添加尋路到該請求。 要請求解析靜態資源,比如一個js腳本,使用方法:

<script src="/parse/public/javascripts/test.js" 
    language="javascript" type="text/javascript" ></script> 

不幸的是,你不能使用#{script 'test.js' /}格式,因爲腳本標籤查找靜態文件。爲了糾正這種令人厭煩的情緒,這裏有一個無恥的腳本標籤:#{parsescript 'test.js'/}標籤。它應該去/views/tags/parsescript.tag

{ 
* insert a parsescript tag in the template. 
* by convention, referred script must be put under /public/javascripts 
* src  (required) : script filename, without the leading path "/public/javascripts" 
* id  (opt.)  : sets script id attribute 
* charset (opt.)  : sets source encoding - defaults to current response encoding 
* 
* #{parsescript id:'datepicker' , src:'ui/ui.datepicker.js', charset:'${_response_encoding}' /} 
}* 
%{ 
    (_arg) && (_src = _arg); 

    if (!_src) { 
     throw new play.exceptions.TagInternalException("src attribute cannot be empty for script tag"); 
    } 
    _src = "/public/javascripts/" + _src 
    try { 
     _abs = play.mvc.Router.reverseWithCheck(_src, play.Play.getVirtualFile(_src), false); 
    } catch (Exception ex) { 
     throw new play.exceptions.TagInternalException("File not found: " + _src); 
    } 
}% 
<script type="text/javascript" language="javascript"#{if _id} id="${_id}"#{/if}#{if _charset} charset="${_charset}"#{/if} src="/parse${_abs}"></script> 

它的工作原理完全一樣的#{script /}標籤,但返回之前分析文件:#{parsescript 'test.js' /}

一個同樣可以無恥地破解#{stylesheet /}標籤,但我想我已經採取已經有足夠的空間了。