سؤال

Basically, I want to iterate over a list of properties to render a list of components. I'm using a component-type of the UIComponent because I need a separate scope for each component. The component works, but I don't know how to give it parameters from the list.

Here is a simple test :

<ul>
    <li>
        <h:outputText value="test"/>
        <h:outputLabel value=" : "/>
        <bf:testA service="test"/>
        <h:outputLabel value=" : "/>
        <bf:testB service="test"/>
    </li>
    <c:forEach items='#{serviceList.val}' var="serviceval">
        <li>
            <h:outputText value="#{serviceval}"/>
            <h:outputLabel value=" : "/>
            <bf:testA service="#{serviceval}"/>
            <h:outputLabel value=" : "/>
            <bf:testB service="#{serviceval}"/>
        </li>
    </c:forEach>
    <ui:repeat value="#{serviceList.val}" var="serviceval">
        <li>
            <h:outputText value="#{serviceval}"/>
            <h:outputLabel value=" : "/>
            <bf:testA service="#{serviceval}"/>
            <h:outputLabel value=" : "/>
            <bf:testB service="#{serviceval}"/>
        </li>
    </ui:repeat>
</ul>

Bellow testA which works :

<c:interface>
    <c:attribute name="service" />
</c:interface>

<c:implementation>
    <h:outputText value="#{cc.attrs.service}"/>
</c:implementation>

and testB which doesn't :

<c:interface componentType="testBComponent">
    <c:attribute name="service" />
</c:interface>

<c:implementation>
    <h:outputText value="#{cc.attrs.service}"/>
</c:implementation>

I need testB because it uses the component-type.

My TestBComponent is just a simple POJO for this test :

@FacesComponent(value="testBComponent")
public class TestBComponent extends UINamingContainer
{
    private String service;
    public TestBComponent()
    {
        service = "Failed";
    }

    public String getService()
    {
        return service;
    }

    public void setService(String service)
    {
        this.service = service;
    }
}

Here are the results :

  • test : test : test
  • test1 : test1 : Failed
  • test2 : test2 : Failed
  • test3 : test3 : Failed
  • test1 : test1 : Failed
  • test2 : test2 : Failed
  • test3 : test3 : Failed

Tested on Tomcat 8 with : jsf-myfaces : 2.1.13 jsf-mojarra : 2.2.4

I'm having a hard time finding documentation about build and render time with composites.

هل كانت مفيدة؟

المحلول

You're not taking care of the component's state.

Use StateHelper as available by the inherited getStateHelper() method.

@FacesComponent(value="testBComponent")
public class TestBComponent extends UINamingContainer {

    public TestBComponent() {
        setService("Failed");
    }

    public String getService() {
        return (String) getStateHelper().eval("service");
    }

    public void setService(String service) {
        getStateHelper().put("service", service);
    }

}

See also:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top