为什么渲染响应阶段使用旧数据?

时间:2011-02-20 15:09:08

标签: java jsf jsf-2 lifecycle

我有一个dataTable,每行都有一个commandButton,它从ManagedBean调用一个方法,当前项目ID如下所示:

<h:commandButton action="#{myBean.doStuff(item.id)}" value="click me"/>

这非常有效,除了渲染响应阶段再次使用另一个(可能是旧的?)id调用doStuff方法 。我用PhaseListener调查了这个问题:

...stuff...
INFO: START PHASE INVOKE_APPLICATION 5
INFO: selecting item with Id: 11
INFO: selected item: new_item
INFO: END PHASE INVOKE_APPLICATION 5
INFO: START PHASE RENDER_RESPONSE 6
INFO: selecting item with Id: 3
INFO: selected item: test1
INFO: END PHASE RENDER_RESPONSE 6
...more stuff...

new_item是我想要的,test1就是我得到的。

那么为什么doStuff方法会在渲染响应阶段被调用,为什么它会使用错误的值呢?

编辑:我正在使用JSF 2.0

1 个答案:

答案 0 :(得分:1)

这通常不会有问题。例如。考虑以下几个方面:

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

    <h:body>    
        <h:form>

            <h:dataTable value="#{tableBean.items}" var="item">

                <h:column>
                    #{item}                
                </h:column>

                <h:column>
                    <h:commandButton value="click" action="#{tableBean.doAction(item)}" />
                </h:column>

            </h:dataTable>

        </h:form>

    </h:body>
</html>

和以下支持bean:

@ManagedBean
@ViewScoped
public class TableBean {

    private List<String> items;

    @PostConstruct
    public void init() {        
        items = new ArrayList<String>();
        items.add("bar");
        items.add("kaz");
        items.add("foo");        
    }

    public String doAction(String string) {
        System.out.println(string);
        return "";
    }

    public List<String> getItems() {
        return items;
    }    

}

这不会在渲染响应阶段打印任何额外内容。也许您需要显示更多代码。您还可以尝试将问题抽象为最基本的问题。如果它然后一步一步地添加你的其他代码,直到你看到它破碎。

相关问题