如何使用支持组件将属性从复合组件传递到辅助bean?

Ana*_*oly 7 jsf composite-component jsf-2

我的facelet页面中有以下代码:

  <hc:rangeChooser1 id="range_chooser" 
                    from="#{testBean.from}"
                    to="#{testBean.to}"
                    listener="#{testBean.update}"
                    text="#{testBean.text}">
        <f:ajax event="rangeSelected"
                execute="@this"
                listener="#{testBean.update}"                   
                render=":form:growl range_chooser"/>
    </hc:rangeChooser1>
Run Code Online (Sandbox Code Playgroud)

这是我的复合组件:

<ui:component xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:p="http://primefaces.org/ui">
    <cc:interface componentType="rangeChooser">
        <!-- Define component attributes here -->
        <cc:clientBehavior name="rangeSelected" event="change" targets="hiddenValue"/>
        <cc:attribute name="from" type="java.util.Calendar"/>
        <cc:attribute name="to" type="java.util.Calendar"/>
        <cc:attribute name="text" type="java.lang.String"/>

    </cc:interface>


    <cc:implementation>

        <div id="#{cc.clientId}">
                 ...
                <p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
                 ...
        </div>
    </cc:implementation>
</ui:component>
Run Code Online (Sandbox Code Playgroud)

我如何通过属性from,totext从复合组件支持豆?我的意思是将这些值注入后备组件,而不是通过

<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
Run Code Online (Sandbox Code Playgroud)

更新:有更正确的定义是什么,我需要:能够变异这是我从传递对象backing beancomposite component内部backing componentcomposite component.因此,当我执行processexecutecomposite component获得更新的值.

这是我的后盾组件:

@FacesComponent("rangeChooser")
public class RangeChooser extends UIInput implements NamingContainer  {
    private String text;
    private Calendar from;
    private Calendar to;

    @Override
    public void encodeBegin(FacesContext context) throws IOException{

        super.encodeBegin(context);
    }


    public String getText() {
        String text = (String)getStateHelper().get(PropertyKeys.text);
        return text;
    }

    public void setText(String text) {
        getStateHelper().put(PropertyKeys.text, text);
    }

    /*
        same getters and setters for Calendar objects, from and to
    */

}
Run Code Online (Sandbox Code Playgroud)

我只是想不通如何继续前进?一般来说,我需要从中取一个值<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>并将其转换为两个Calendars对象fromto.如果有人可以从这里指出我正确的方向,那将是很棒的.我知道我需要使用 getAttributes().put(key,value)但不知道在哪里放这个代码.先感谢您.

Mic*_*tti 5

根据您的意见,这是您所期望的.

请注意,即使此实现有效,它在概念上也是不正确的!

您正在考虑fromto为输入(不输入组件,但输入值),并text作为输出.这不是JSF的工作方式!

但是,在这里

<cc:interface componentType="rangeComponent">
    <cc:attribute name="from" />
    <cc:attribute name="to" />
    <cc:clientBehavior name="rangeSelected" event="dateSelect" targets="from to"/>
</cc:interface>

<cc:implementation>

    <div id="#{cc.clientId}">
        <p:calendar id="from" value="#{cc.attrs.from}"/>
        <p:calendar id="to" value="#{cc.attrs.to}"/>
    </div>

</cc:implementation>
Run Code Online (Sandbox Code Playgroud)

用于页面:

<h:form>
    <e:inputRange from="#{rangeBean.from}" to="#{rangeBean.to}" text="#{rangeBean.text}">
        <p:ajax event="rangeSelected" process="@namingcontainer" update="@form:output" listener="#{rangeBean.onChange}" />
    </e:inputRange>

    <h:panelGrid id="output" columns="1">
        <h:outputText value="#{rangeBean.from}"/>
        <h:outputText value="#{rangeBean.to}"/>
        <h:outputText value="#{rangeBean.text}"/>
    </h:panelGrid>
</h:form>
Run Code Online (Sandbox Code Playgroud)

使用此支持组件:

@FacesComponent("rangeComponent")
public class RangeComponent extends UINamingContainer
{
    @Override
    public void processUpdates(FacesContext context)
    {
        Objects.requireNonNull(context);

        if(!isRendered())
        {
            return;
        }

        super.processUpdates(context);

        try
        {
            Date from = (Date) getValueExpression("from").getValue(context.getELContext());
            Date to = (Date) getValueExpression("to").getValue(context.getELContext());

            ValueExpression ve = getValueExpression("text");
            if(ve != null)
            {
                ve.setValue(context.getELContext(), from + " - " + to);
            }
        }
        catch(RuntimeException e)
        {
            context.renderResponse();
            throw e;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这个支持bean:

@ManagedBean
@ViewScoped
public class RangeBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    private Date from = new Date(1000000000);
    private Date to = new Date(2000000000);
    private String text = "range not set";

    public void onChange(SelectEvent event)
    {
        Messages.addGlobalInfo("[{0}] changed: [{1}]", event.getComponent().getId(), event.getObject());
    }

    // getters/setters
}
Run Code Online (Sandbox Code Playgroud)