2010-12-19 17 views
4

我使用JSF 2.0,並且正在尋找包括網頁上的所有從給定文件夾中的JavaScript的一種手段,即像做是否可以在JSF中包含來自一個文件夾的所有javascripts文件?

<h:outputScript library="javascript" name="*.js" target="head" /> 

是這種事情甚至可能嗎?我應該使用java代碼編寫自定義組件來實現這一目標嗎?

感謝您的幫助,
塞巴斯蒂安·特龍普

+0

我沒有答案,但這確實是一個有趣的問題。如果標準設施無法做到這一點,那麼它將成爲JSF 2.1的一項重要功能。 – 2010-12-19 11:27:29

回答

3

不錯的主意。這不受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這裏工作正常。您可以使用像*.jsprefix*.js這樣的模式。特定的代碼示例僅與特定的JSF實現緊密結合以節省代碼樣板。它還要求在部署時擴展WAR,否則將無法瀏覽目錄File#listFiles()(因此排除某些(較舊的)servlet容器版本/配置)。對於其他JSF實現你將不得不擴大其ScriptRenderer代替,或者寫一個全新的,如果你想成爲獨立實現(這應該是相當簡單不過,只要看看標準ScriptRenderer來源,如果你stucks)。

+0

感謝您的支持。與此同時,我發現了一些需要包括幾個javascript文件的工作,但我肯定會在後期保留這些文件。 – 2010-12-21 13:00:10

+0

你(自動)壓縮/縮小所有鬆散的JS文件到一個單一的JS文件?這確實也經常完成以節省HTTP請求的數量。 – BalusC 2010-12-21 13:19:23

3

我沒有測試這一點,但如果通配符不被接受,你可以在後臺bean獲取通過Java代碼文件列表,並利用它們插入頭c:forEachui:repeat,如:

<ui:repeat value="#{bean.files}" var="file"> 
    <h:outputScript library="javascript" name="#{file}" target="head" /> 
</ui:repeat> 

請注意,你不能給的絕對路徑h:outputScript但您必須從他們的前綴(該部分preceeds的JSF資源路徑)。

相關問題