문제

I build a composite component which takes an input id and generate a table . Then I make a page which accepts a GET parameter using <f:viewParam> likes this:

<f:metadata>
        <f:viewParam name="id" value="#{aBean.id}" />
</f:metadata>
<util:aCompositeComponent inputId="#{aBean.id}" />

The markup of the composite component is :

<cc:interface componentType="compositeComponentBacking">
    <cc:attribute name="inputId" type="java.lang.Integer"  />
</cc:interface>

<cc:implementation>         
        /**
          Use #{cc.result} to build a HTML table to present a result
        **/
</cc:implementation>

And the backing bean of the composite component is:

@FacesComponent("compositeComponentBacking")
public class CompositeComponentBacking extends UINamingContainer {

    private Integer inputId;

    public List<Result> getResult() {
        
        //Use inputId to query service to return result
        return result;
    }

    public Integer getInputId() {
        return inputId;
    }

    public void getInputId(Integer inputId) {
        this.inputId = inputId;
    }

}

GET parameter can be bounded to #{aBean.id} but #{aBean.id} cannot be passed into the composite component and it always remain null inside the composite component . How can I pass the GET parameter to the composite component?


Update :

I finally solve the problem .I found that when using the composite component , if the input attribute is constant (eg <util:aCompositeComponent inputId="1"/>) ,this constant can be set to CompositeComponentBacking 's inputId field. But if I use the composite with the input attribute is an EL expression (eg <util:aCompositeComponent inputId="#{aBean.id}"/> , the value of the EL expression cannot be set to CompositeComponentBacking 's inputId field. I have to programmatically get the value by evaluating #{cc.attrs.inputId} inside CompositeComponentBacking . Is it the normal behavior ?

도움이 되었습니까?

해결책

Attribute values representing value expressions are set via setValueExpression("attributeName", valueExpression), not via setAttributeName(evaluatedValue). You know, JSF/Facelets EL is deferred, not implicit.

You should in the getResult() basically be obtaining the evaluated value by getAttributes() map:

public List<Result> getResult() {
    Integer inputId = (Integer) getAttributes().get("inputId");
    // ...
}

If you really want to add a getter and setter, then delegate to getStateHelper().

public Integer getInputId() {
    return (Integer) getStateHelper().eval("inputId");
}

public void setInputId(Integer inputId) {
    getStateHelper().put("inputId", inputId);
}

(note: don't mix them; getAttributes().get() would scan for a getter first and then invoke it; if you were using getAttributes().get() inside the getter itself, it would call itself in an infinite loop causing an error represented by this site's name)

다른 팁

If you're certain the value is there, you can use

<util:aComposite inputId="#{param.id}" />

to access request parameter id. It won't be validated, converted or whatever.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top