在复合组件中使用f:属性

时间:2012-01-27 11:42:12

标签: jsf-2 attributes composite-component

我们在这里有一个非常简单的场景(在我们的观点中)。但是我们在复合组件和f:属性标签上遇到了问题。我会尽量保持代码尽可能简单。

复合组件:

<cc:interface name="button">
    ...
    <cc:attribute
        name="actionListener"
        required="true"
        method-signature="void f(javax.faces.event.ActionEvent)"
        target="button"
        shortDescription="The action listener for this button." />
    ...
</cc:interface>

<cc:implementation>
    <ice:commandButton
        ...
        actionListener="#{cc.attrs.actionListener}"
        ...>

        <cc:insertChildren />
    </ice:commandButton>
</cc:implementation>

...现在我们使用这样的组件:

<ctrl:button
    ...
    actionListener="#{bean.method}"
    ...>
    <f:attribute name="objectId" value="#{someObject.id}" />
</ctrl:button>

现在我们需要访问动作侦听器方法中的“objectId”属性。我们已经尝试过这样的事情:

public void method(ActionEvent event)
{
    ...
    event.getComponent().getAttributes().get("objectId");
    ...
}

但属性映射不包含objectId。这种方法有什么问题吗?解决这个问题的推荐方法是什么?

如果有人可以帮助我们,那会很好。

谢谢! SlimShady

2 个答案:

答案 0 :(得分:5)

这个<f:attribute> hack是JSF 1.0 / 1.1的遗留物,当时无法将对象作为命令按钮/链接的附加参数传递。从JSF 1.2开始,你应该使用<f:setPropertyActionListener>

<ctrl:button action="#{bean.method}">
    <f:setPropertyActionListener target="#{bean.objectId}" value="#{someObject.id}" />
</ctrl:button>

由于EL 2.2(它是Servlet 3.0的标准部分,但是在JBoss EL的帮助下可以实现Servlet 2.5),你甚至可以将整个对象作为方法参数传递:

<ctrl:button action="#{bean.method(someObject.id)}" />

答案 1 :(得分:3)

我设法在以下设置中读取传入cc的属性。

<test:inner>
    <f:attribute name="fAttribute" value="myAttributeValue" />
</test:inner>

<cc:implementation>
    <h:commandButton value="button" actionListener="#{testBean.actionListener}" >
        <f:attribute name="innerAttribute" value="innerAttributeValue" />
            <cc:insertChildren /> <!-- not necessary, I hoped it would pass the outer attribute --->
    </h:commandButton>
</cc:implementation>

public void actionListener(ActionEvent event) {
    event.getComponent().getNamingContainer().getAttributes().get("fAttribute") 
    // > myAttributeValue
    event.getComponent().getAttributes().get("innerAttribute") 
    // > innerAttributeValue
}

诀窍是在按钮的命名容器中搜索。因此,cc始终是一个命名容器,您可以确保最终进入内部组件。

我不确定这是否是它的意图,但据我所知,命名内容会为其子女收集这些属性。

问:有没有人知道如果没有将属性传递给按钮被认为是Mojarra / JSF中的错误?