質問

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