Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向JSF中的Primefaces自动完成组件添加自定义属性_Jsf_Jsf 2_Primefaces_Custom Component - Fatal编程技术网

向JSF中的Primefaces自动完成组件添加自定义属性

向JSF中的Primefaces自动完成组件添加自定义属性,jsf,jsf-2,primefaces,custom-component,Jsf,Jsf 2,Primefaces,Custom Component,我询问了a中的传递属性,发现我可以为组件创建自定义渲染器,但问题是我的自定义渲染器将用于项目(站点范围)中的每个p:autocomplete。因此,我选择创建一个自定义组件,它扩展了org.primefaces.component.autocomplete.autocomplete,并将必要的属性添加到文本框中 我最初的想法是添加构造函数,但它似乎不起作用,因为此时属性映射为null: @FacesComponent("com.mycomponents.SiteSearch") public c

我询问了a中的传递属性,发现我可以为
组件创建自定义渲染器,但问题是我的自定义渲染器将用于项目(站点范围)中的每个p:autocomplete。因此,我选择创建一个自定义组件,它扩展了
org.primefaces.component.autocomplete.autocomplete
,并将必要的属性添加到文本框中

我最初的想法是添加构造函数,但它似乎不起作用,因为此时属性映射为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");
    }   
}
@FacesComponent(“com.mycomponents.SiteSearch”)
公共类SiteSearch扩展了自动完成{
公共网站搜索(){
Map attrs=getAttributes();
属性put(“x-webkit-speech”,null);
属性放置(“x-webkit-Grammar”,“内置:搜索”);
attrs.put(“onwebkitspeechchange”,“this.form.submit();”;
属性放置(“占位符”,“输入搜索词”);
}   
}
我的另一个想法是将这个自定义组件保留为空(empty类),然后指定一个扩展
org.primefaces.component.autocomplete.AutoCompleteRenderer
的自定义呈现程序,并修改其中的属性


说到底,我只需要一种方法将这些属性与这个文本框分开,这样在p:autoComplete上放置一个自定义渲染器就行不通了(除非我可以对这个p:autoComplete使用renderType=attribute?).

如果您需要使用不同于
的渲染器的特定组件,那么您真的无法创建具有自己族和组件类型的自定义组件。您仍然可以扩展PrimeFaces
AutoComplete
(及其渲染器)来保存一些样板代码

在自定义组件中,需要为这些属性提供getter。您也可以指定setter,这样您就可以始终覆盖视图端的默认值。这些getter/setter应该反过来委托给

x-webkit-*
属性只有一个小问题。
-
是Java标识符中的非法字符。因此,您必须重命名getter/setter,并在某种程度上更改呈现器,因为标准呈现器依赖于组件属性名称与标记属性名称完全相同更新:我理解
x-webkit-speech
应该按原样呈现(因此,不需要getter/setter),而且
x-webkit-grammar
实际上是一个打字错误,应该是
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);
    }

}
请注意,getter指定了所有默认值。如果
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);
    }

}
<my:siteSearch grammar="builtin:language" onspeechchange="alert('peek-a-boo')" placeholder="Search" />
要在视图中使用它,我们当然需要将其注册为标记。创建
/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>
最后,您可以按如下方式使用它:

<html ... xmlns:my="http://example.com/ui">
...
<my:siteSearch />

...
您甚至可以指定其他属性,这些属性将覆盖组件中设置的默认值:

@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);
    }

}
<my:siteSearch grammar="builtin:language" onspeechchange="alert('peek-a-boo')" placeholder="Search" />


对于属性上的IDE自动完成,您需要在
my.taglib.xml

正在观看的系列(House MD now)中的
声明中将每个属性指定为单独的
。有点耐心:)哈哈。不是问题。我想,每当我看到一个JSF问题,我都会自动地假设你的问题就是答案,甚至连看都不看。有人能说JSF忍者吗?@BalusC,如何为我的自定义组件实现同样的功能,它使用类似给定的composite创建