我使用JSF 2.0,並且正在尋找包括網頁上的所有從給定文件夾中的JavaScript的一種手段,即像做是否可以在JSF中包含來自一個文件夾的所有javascripts文件?
<h:outputScript library="javascript" name="*.js" target="head" />
是這種事情甚至可能嗎?我應該使用java代碼編寫自定義組件來實現這一目標嗎?
感謝您的幫助,
塞巴斯蒂安·特龍普
我使用JSF 2.0,並且正在尋找包括網頁上的所有從給定文件夾中的JavaScript的一種手段,即像做是否可以在JSF中包含來自一個文件夾的所有javascripts文件?
<h:outputScript library="javascript" name="*.js" target="head" />
是這種事情甚至可能嗎?我應該使用java代碼編寫自定義組件來實現這一目標嗎?
感謝您的幫助,
塞巴斯蒂安·特龍普
不錯的主意。這不受JSF API支持,但理論上可以使用自定義腳本渲染器。我打了一些東西,確實有可能。只要創建一個MultiScriptRenderer
其中extends ScriptRenderer
並覆蓋encodeEnd()
,以檢查是否name
屬性包含通配符*
,然後通過掃描相應的處理匹配的資源文件夾此樣式文件。
這裏有一個開球例如:
package com.example;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.sun.faces.renderkit.html_basic.ScriptRenderer;
public class MultiScriptRenderer extends ScriptRenderer {
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
Map<String, Object> attributes = component.getAttributes();
String name = (String) attributes.get("name");
if (name.contains("*")) {
String pattern = name.replace(".", "\\.").replace("*", ".*");
String library = (String) attributes.get("library");
File root = new File(context.getExternalContext().getRealPath("/resources/" + (library != null ? library : "")));
for (File file : root.listFiles()) {
if (file.getName().matches(pattern)) {
attributes.put("name", file.getName());
super.encodeEnd(context, component);
}
}
attributes.put("name", name); // Put original name back. You never know.
} else {
super.encodeEnd(context, component);
}
}
}
在faces-config.xml
註冊爲如下(對不起,@FacesRenderer
註釋行不通的,直到它固定在JSF 2.2這個特定的極端情況下,還看到JSF issue 1748):
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.resource.Script</renderer-type>
<renderer-class>com.example.MultiScriptRenderer</renderer-class>
</renderer>
</render-kit>
在Mojarra 2.0.3這裏工作正常。您可以使用像*.js
和prefix*.js
這樣的模式。特定的代碼示例僅與特定的JSF實現緊密結合以節省代碼樣板。它還要求在部署時擴展WAR,否則將無法瀏覽目錄File#listFiles()
(因此排除某些(較舊的)servlet容器版本/配置)。對於其他JSF實現你將不得不擴大其ScriptRenderer
代替,或者寫一個全新的,如果你想成爲獨立實現(這應該是相當簡單不過,只要看看標準ScriptRenderer
來源,如果你stucks)。
感謝您的支持。與此同時,我發現了一些需要包括幾個javascript文件的工作,但我肯定會在後期保留這些文件。 – 2010-12-21 13:00:10
你(自動)壓縮/縮小所有鬆散的JS文件到一個單一的JS文件?這確實也經常完成以節省HTTP請求的數量。 – BalusC 2010-12-21 13:19:23
我沒有測試這一點,但如果通配符不被接受,你可以在後臺bean獲取通過Java代碼文件列表,並利用它們插入頭c:forEach
或ui:repeat
,如:
<ui:repeat value="#{bean.files}" var="file">
<h:outputScript library="javascript" name="#{file}" target="head" />
</ui:repeat>
請注意,你不能給的絕對路徑h:outputScript
但您必須從他們的前綴(該部分preceeds的JSF資源路徑)。
我沒有答案,但這確實是一個有趣的問題。如果標準設施無法做到這一點,那麼它將成爲JSF 2.1的一項重要功能。 – 2010-12-19 11:27:29