为什么导航只在辅助bean是会话范围时才能正常工作?

时间:2011-06-14 07:21:11

标签: ajax jsf-2 glassfish-3

考虑以下页面(为简洁起见省略了标题和内容):

<h:body>
    <h:form>
        <h:inputText 
            id="theInput"
            value="#{theBean.text}">
            <f:ajax render="theButton" />
        </h:inputText>
        <h:commandButton 
            id="theButton" 
            value="Result" 
            disabled="#{theBean.disabled}"
            action="result" />
    </h:form>
</h:body>

TheBean看起来像这样:

@Named
@RequestScoped
public class TheBean {
    String text;

    public TheBean() {
        this.text = "test";
    }

    public String getText() {
        return this.text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public boolean isDisabled() {
        return this.text.equals("test");
    }
}

result.xhtml是占位符,显示一些静态文本。

这个想法是仅在输入的文本有效时启用该按钮(在这种情况下与默认值不同)。如果我输入test以外的其他内容,它会正常启用,但是当我点击按钮时,它不会导航到result。但是,如果我执行以下操作之一,它会起作用:

  1. 我始终启用按钮。这让我很困惑,因为在上面的示例中,按钮已正确启用,它只会导航到下一页。如果我一直让它一直启用,为什么会改变呢?
  2. 我将TheBean的范围更改为@SessionScoped。我也不明白这一点。支持bean的范围如何影响页面导航?示例中的其他所有内容似乎与@RequestScoped一样。
  3. 我真的想保留TheBean请求范围。有没有办法让它成为导航工作而不会使其成为会话范围的?

1 个答案:

答案 0 :(得分:2)

您的bean是请求作用域,这意味着每个HTTP请求(也是ajax请求!)都会创建一个全新的bean。更改输入时,ajax请求会创建一个新bean并设置该值。当您按下按钮时,正常请求会创建一个新bean(因此ajax设置的值会丢失!)并确定该按钮是否有资格被调用 - 这不是 - 因此不会调用该操作。 / p>

视图范围旨在克服这类问题。将bean放在视图范围内。

@ManagedBean
@ViewScoped
public class TheBean {

这样,只要你通过普通或ajax请求与同一个视图交互,bean就会存在。

抱歉,我不知道从正确的CDI声明是什么。它至少被称为“对话范围”。