如果您需要使用與<p:autoComplete>
不同的渲染器的特定組件,那麼您實際上無法繞過使用其自己的族和組件類型創建自定義組件。您仍然可以擴展PrimeFaces AutoComplete
(及其渲染器)以保存一些樣板代碼。
在自定義組件中,您需要爲這些屬性提供獲取者。你也可以很好的指定setter,這樣你總是可以覆蓋視圖中的默認值。那些獲得者/安排者應該依次代表StateHelper
。
x-webkit-*
屬性只有一個小問題。 -
是Java標識符中的非法字符。因此,您必須重新命名getter/setters並更改渲染器,因爲標準渲染器依賴於組件屬性名稱與標記屬性名稱完全相同。 更新:據我所知,x-webkit-speech
應該只是呈現(因此,沒有getter/setter必要),並且x-webkit-grammer
實際上是一個錯字,它應該是x-webkit-grammar
。
這裏的SiteSearch
組件如何看起來像:
@FacesComponent(SiteSearch.COMPONENT_TYPE)
public class SiteSearch extends AutoComplete {
public static final String COMPONENT_FAMILY = "com.example";
public static final String COMPONENT_TYPE = "com.example.SiteSearch";
private enum PropertyKeys {
grammar, onspeechchange, placeholder
}
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
@Override
public String getRendererType() {
return SiteSearchRenderer.RENDERER_TYPE;
}
public String getGrammar() {
return (String) getStateHelper().eval(PropertyKeys.grammar, "builtin:search");
}
public void setGrammar(String grammar) {
getStateHelper().put(PropertyKeys.grammar, grammar);
}
public String getOnspeechchange() {
return (String) getStateHelper().eval(PropertyKeys.onspeechchange, "submit()");
}
public void setOnspeechchange(String onspeechchange) {
getStateHelper().put(PropertyKeys.onspeechchange, onspeechchange);
}
public String getPlaceholder() {
return (String) getStateHelper().eval(PropertyKeys.placeholder, "Enter a Search Term");
}
public void setPlaceholder(String placeholder) {
getStateHelper().put(PropertyKeys.placeholder, placeholder);
}
}
請注意,干將有指定的所有默認值。如果eval()
返回null
,則將返回默認值。我也在某種程度上中和了屬性名稱,以便通過相應地修改渲染器來將它重用於任何未來的非Webkit瀏覽器。
而這裏的SiteSearchRenderer
渲染器看起來應該像上面的成分:
@FacesRenderer(
componentFamily=SiteSearch.COMPONENT_FAMILY,
rendererType=SiteSearchRenderer.RENDERER_TYPE
)
public class SiteSearchRenderer extends AutoCompleteRenderer {
public static final String RENDERER_TYPE = "com.example.SiteSearchRenderer";
@Override
protected void renderPassThruAttributes(FacesContext facesContext, UIComponent component, String[] attrs) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
writer.writeAttribute("x-webkit-speech", "x-webkit-speech", null);
writer.writeAttribute("x-webkit-grammar", component.getAttributes().get("grammar"), "grammar");
writer.writeAttribute("onwebkitspeechchange", component.getAttributes().get("onspeechchange"), "onspeechchange");
writer.writeAttribute("placeholder", component.getAttributes().get("placeholder"), "placeholder");
super.renderPassThruAttributes(facesContext, component, attrs);
}
}
要在視圖中使用它,我們當然需要將其註冊爲標籤。創建/WEB-INF/my.taglib.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/ui</namespace>
<tag>
<tag-name>siteSearch</tag-name>
<component>
<component-type>com.example.SiteSearch</component-type>
<renderer-type>com.example.SiteSearchRenderer</renderer-type>
</component>
</tag>
</facelet-taglib>
請注意,您不需要在faces-config.xml
這一個<renderer>
了。 @FacesRenderer
註釋可以在真正的自定義組件上完成它的工作。因此,請刪除您在上一個問題中創建的faces-config.xml
中的<renderer>
條目。
現在告訴JSF,你有通過以下方面PARAM自定義標籤庫中web.xml
:
<html ... xmlns:my="http://example.com/ui">
...
<my:siteSearch />
你甚至可以指定其他:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
最後,您可以按如下方式使用它將覆蓋組件中默認設置的屬性:
<my:siteSearch grammar="builtin:language" onspeechchange="alert('peek-a-boo')" placeholder="Search" />
對於屬性上的IDE自動完成,您需要在my.taglib.xml
的<tag>
聲明中指定每一個爲單獨的<attribute>
。
@BalusC有什麼想法? – Adam
正在觀看系列(現在的房子MD)。有一點耐心:) – BalusC
哈哈。沒有問題。我想,只要我看到一個JSF問題,我就會自動假設你的答案沒有看到。任何人都可以說JSF忍者? – Adam