jsf - 根据提供的属性初始化复合组件

标签 jsf jsf-2 composite-component

我正在用 Mojarra JSF 编写我的自定义表格复合组件。我还试图将该复合 Material 绑定(bind)到支持组件。目的是能够在复合属性中指定表格的元素数量,稍后绑定(bind)的支持组件将在 View 渲染之前自动生成元素本身。我有这个示例代码:

主页:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:comp="http://java.sun.com/jsf/composite/comp">
<h:head />
<body>
    <h:form>
        <comp:myTable itemNumber="2" />
    </h:form>
</body>
</html>

myTable.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:composite="http://java.sun.com/jsf/composite"
    xmlns:h="http://java.sun.com/jsf/html">

<h:body>
    <composite:interface componentType="components.myTable">
        <composite:attribute name="itemNumber" 
            type="java.lang.Integer" required="true" />
    </composite:interface>

    <composite:implementation>
        <h:dataTable value="#{cc.values}" var="value">
            <h:column headerText="column">
                #{value}
                <h:commandButton value="Action" action="#{cc.action}" />
            </h:column>
        </h:dataTable>
    </composite:implementation>
</h:body>
</html>

MyTable.java:
@FacesComponent("components.myTable")
public class MyTable extends UINamingContainer {

    private List<String> values = new ArrayList<String>();

    public void action() {
        System.out.println("Called");
    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        // Initialize the list according to the element number
        Integer num = (Integer) getAttributes().get("itemNumber");
        for (int i = 0; i < num; i++) {
            values.add("item" + i);
        }
        super.encodeBegin(context);
    }

    public List<String> getValues() {
        return values;
    }

}

问题是表格被正确渲染(在这种情况下有两个项目),但是 action方法没有被调用 当按下线路上的按钮时。

如果我关注 wiki page对于复合组件,我可以让它工作,但必须初始化 List每次getValues()被调用,将逻辑引入getter方法:-(。

有什么想法吗?似乎与覆盖 encodeBegin 相关的问题方法。我还尝试在 markInitialState 上对其进行初始化,但那里还没有属性...

使用 Mojarra 2.1.27 + Tomcat 6-7 和 Mojarra 2.2.5 + Tomcat 7 测试

最佳答案

至于原因,UIComponent实例本质上是请求范围的。回发有效地创建了一个具有 values 等属性的全新实例。重新初始化为默认值。在您的实现中,它仅在 encodeXxx() 期间填充。 ,在 decode() 之后很久才调用其中 Action 事件需要排队,因此为时已晚。

最好在组件初始化的时候填写。如果您想要 @PostConstruct - 类似于 UIComponent 的钩子(Hook)实例,然后是 postAddToView事件是一个很好的候选人。这是在组件实例添加到组件树后直接调用的。

<cc:implementation>
    <f:event type="postAddToView" listener="#{cc.init}" />
    ...
</cc:implementation>


private List<String> values;

public void init() {
    values = new ArrayList<String>();
    Integer num = (Integer) getAttributes().get("value");

    for (int i = 0; i < num; i++) {
        values.add("item" + i);
    }
}

(如果 encodeBegin() 方法不再有用,则删除它)

另一种方法是延迟初始化 getValues()方法。

关于jsf - 根据提供的属性初始化复合组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21525669/

相关文章:

jsf - 如何停用 JSF 标签 (Primefaces)

java - JSF 不解析 #{} 标签

java - 如何完全控制primefaces p :dataGrid pagination with the backing bean?

java - JSF 2.0 h :selectManyListbox f:selectItems - always empty

jsf-2 - 当为其他组件指定了流程属性时,PrimeFaces Ajax监听器未执行

JSF 组合用户界面 :param with composite component

jsf - jsf 中的异常处理 - 在新页面中打印错误消息

jsf - 通过选择复选框启用和禁用组件

jsf - 从复合组件中删除自动生成的j_id

java - 更新复合组件?