为什么导航仅在支持bean处于会话范围内时才能正常工作?

问题描述

| 考虑以下页面(为简洁起见,省略了标题内容):
<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
显示一些静态文本的占位符。 想法是仅在输入的文本有效时才启用按钮(在这种情况下,认设置是不同的)。它起作用,并且如果我输入的不是than4ѭ,则按钮已正确启用,但是当我单击该按钮时,它不会导航到
result
。但是,如果我执行以下操作之一,它将起作用: 我使该按钮始终处于启用状态。这让我感到困惑,因为在上面的示例中,正确启用了按钮,因此它仅不会导航到下一页。如果我一直保持启用状态,为什么会有这种更改? 我将
TheBean
的范围更改为
@SessionScoped
。我也不明白。支持bean的范围如何影响页面导航?示例中的所有其他内容似乎都与
@RequestScoped
相同。 我真的很想保留
TheBean
请求范围。有没有什么方法可以使它在不进行会话作用域的情况下正常工作?     

解决方法

        您的bean受请求范围限制,这意味着每个单个HTTP请求(也包括ajax请求!)都会创建一个全新的bean。当您更改输入时,ajax请求将创建一个新bean并设置值。当您按下按钮时,普通请求将创建一个新bean(因此,由ajax设置的值将丢失!)并确定按钮是否适合被调用(不是),因此不会调用该动作。 视图范围旨在克服此类问题。将bean放入视图范围。
@ManagedBean
@ViewScoped
public class TheBean {
这样,只要您通过普通或Ajax请求与同一个视图进行交互,该Bean就会一直存在。 抱歉,我不知道正确的CDI声明到底是怎么回事。至少称为“对话范围”。