简体   繁体   English

<ui:repeat>在JSF 2.0中打破了方法的执行顺序

[英]<ui:repeat> in JSF 2.0 breaks methods execution order

I have very simple JSF 2.0 application (see below). 我有一个非常简单的JSF 2.0应用程序(请参见下文)。 The problem is that when ui:repeat is present, execution order (I check it using breakpoints in debugger) is strange. 问题是当存在ui:repeat时,执行顺序(我在调试器中使用断点检查它)很奇怪。

After I submit form, SecondBean.initSomething() is called before FirstBean.setFirstFormField() . 我提交表单后, SecondBean.initSomething()之前被调用FirstBean.setFirstFormField() If I change type of something to String and delete ui:repeat from index.jsf and use just h:outputText then everything works as expected, FirstBean.setFirstFormField() is called before SecondBean.initSomething() . 如果我将something类型更改为String并从index.jsf删除ui:repeat并仅使用h:outputText那么一切都会按预期进行, FirstBean.setFirstFormField()SecondBean.initSomething()之前调用SecondBean.initSomething()

What I'm doing wrong? 我做错了什么?

I'm using JDeveloper Studio Edition 11.1.2.2.0 and its stack (WebLogic 10.3.5.0, Java 6 and JSF 2.0). 我正在使用JDeveloper Studio Edition 11.1.2.2.0及其堆栈(WebLogic 10.3.5.0,Java 6和JSF 2.0)。

Here's the code: 这是代码:

index.jsf: index.jsf:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <h:head></h:head>
        <h:body>
            <h:form>
                <h:panelGrid columns="1">
                    <h:inputText value="#{firstBean.firstFormField}" />
                    <h:commandButton action="#{firstBean.processForm}" value="Submit" />
                </h:panelGrid>
            </h:form>
            <ui:repeat value="#{secondBean.something}" var="variable" >
                <h:outputText value="#{variable}" />
            </ui:repeat>
        </h:body>
    </html>
</f:view>

FirstBean.java: FirstBean.java:

package test.backing;

import javax.faces.bean.*;
import javax.faces.context.FacesContext;

@ManagedBean
@RequestScoped
public class FirstBean {
    private String firstFormField;
    public FirstBean() {
        super();
    }

    public String processForm() {
        FacesContext facesContext;

        facesContext = FacesContext.getCurrentInstance();

        return facesContext.getViewRoot().getViewId();            
    }

    public void setFirstFormField(String firstFormField) {
        this.firstFormField = firstFormField;
    }

    public String getFirstFormField() {
        return this.firstFormField;
    }
}

SecondBean.java: SecondBean.java:

package test.backing;

import java.util.*;

import javax.annotation.PostConstruct;

import javax.faces.bean.*;

@ManagedBean
@RequestScoped
public class SecondBean {
    private List<String> something;

    public SecondBean() {

    }

    @PostConstruct
    public void initSomething() {
        this.something = Arrays.asList("abc", "cde");
    }

    public void setSomething(List<String> something) {
        this.something = something;
    }

    public List<String> getSomething() {
        return this.something;
    }
}

faces-config.xml: faces-config.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee">

</faces-config>

web.xml: web.xml:

<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
  <context-param>
    <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.jsf;*.xhtml</param-value>
  </context-param>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
</web-app>

What I'm doing wrong? 我做错了什么?

Nothing. 没有。 It's working as specified. 它按指定方式工作。 It's just invoked during restoring the view. 它只是在还原视图期间调用的。

If this is causing a specific problem for you, which is unfortunately not described in detail in the question at all, then a solution needs to be sought in a different direction than depending/relying on some specific execution order of bean construction or getter calls relative to the view. 如果这给您造成了一个特定的问题,但是不幸的是根本没有详细描述该问题,那么需要在不同于/依赖于某些特定的Bean构造执行过程或与之相对的getter调用顺序上寻求解决方案。到视图。 At least, that is what you seem to be targeting at for some reason. 至少,出于某种原因,这似乎是您的目标。


Unrelated to the concrete problem, in that processForm() action method you can also just return null to navigate back to the current view. 具体问题无关 ,在该processForm()动作方法中,您还可以返回null导航回到当前视图。 That's much simpler than the current clumsy approach. 这比当前笨拙的方法要简单得多。

This is how the JSF cycle works. 这就是JSF循环的工作方式。 The order is correct... 顺序正确...

You need to change the manner you are doing agreeing with the rules of the JSF framework. 您需要更改您与JSF框架规则达成一致的方式。 Learn the phases of the JSF cycle, may this can help you. 了解JSF周期的各个阶段,可能对您有帮助。

您可以使用h:dataTable,它不会在还原阶段填充值,而是在updateModel pahse之后填充值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM