我询问different question中的传递属性,发现我可以为<p:autocomplete>
组件创建自定义渲染器,但问题是我的自定义渲染器将用于我项目中的每个p:autocomplete (站点范围)。因此,我选择创建一个扩展org.primefaces.component.autocomplete.AutoComplete
的自定义组件,并将必要的属性添加到文本框中。
我最初的想法是添加一个构造函数,但它似乎不起作用,因为此时属性map为null:
@FacesComponent("com.mycomponents.SiteSearch")
public class SiteSearch extends AutoComplete {
public SiteSearch() {
Map<String,Object> attrs = getAttributes();
attrs.put("x-webkit-speech", null);
attrs.put("x-webkit-grammer", "builtin:search");
attrs.put("onwebkitspeechchange", "this.form.submit();");
attrs.put("placeholder", "Enter a Search Term");
}
}
我的另一个想法是将此自定义组件留空(空类),然后指定扩展org.primefaces.component.autocomplete.AutoCompleteRenderer
的自定义渲染器并修改其中的属性。
毕竟说完了之后,我只需要一种方法将这些属性与这一个文本框分开,这样只需在p:autoComplete上放一个自定义渲染器就行不通了(除非我可以使用renderType = attribute对于这一个p:autoComplete?)。
答案 0 :(得分:18)
如果您需要使用与<p:autoComplete>
不同的渲染器的特定组件,那么您实际上无法创建具有自己的族和组件类型的自定义组件。您仍然可以扩展PrimeFaces AutoComplete
(及其渲染器)以保存一些样板代码。
在自定义组件中,您需要为这些属性提供getter。你也可以很好地指定setter,这样你总是可以覆盖视图端的默认值。那些getter / setter应该委托给StateHelper
。
x-webkit-*
属性只有一点问题。 -
是Java标识符中的非法字符。因此,您必须重命名getter / setter并稍微更改渲染器,因为标准渲染器依赖于组件属性名称与标记属性名称完全相同。 更新:我了解x-webkit-speech
应该按原样呈现(因此,不需要getter / setter)并且x-webkit-grammer
实际上是一个拼写错误,它应该是{{1} }}
以下是x-webkit-grammar
组件的外观:
SiteSearch
请注意,getter具有指定的所有默认值。如果@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()
,则会返回默认值。我还稍微中了一下属性名称,以便只需相应地修改渲染器就可以将它重用于任何未来的非webkit浏览器。
以下是上述组件的null
渲染器的外观:
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>
中不再需要<renderer>
。 faces-config.xml
注释可以在真实的自定义组件上完成它的工作。因此,请根据您之前的问题删除您创建的@FacesRenderer
中的<renderer>
条目。
现在告诉JSF你已经通过faces-config.xml
中的以下上下文参数获得了自定义taglib:
web.xml
最后你可以按如下方式使用它:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
您甚至可以指定其他属性,这些属性将覆盖组件中设置的默认值:
<html ... xmlns:my="http://example.com/ui">
...
<my:siteSearch />
对于属性的IDE自动填充,您需要在<my:siteSearch grammar="builtin:language" onspeechchange="alert('peek-a-boo')" placeholder="Search" />
的{{1}}声明中将每个属性指定为单独的<attribute>
。