考虑以下页面(为简洁起见省略了标题和内容):
<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
。但是,如果我执行以下操作之一,它会起作用:
TheBean
的范围更改为@SessionScoped
。我也不明白这一点。支持bean的范围如何影响页面导航?示例中的其他所有内容似乎与@RequestScoped
一样。我真的想保留TheBean
请求范围。有没有办法让它成为导航工作而不会使其成为会话范围的?
答案 0 :(得分:2)
您的bean是请求作用域,这意味着每个HTTP请求(也是ajax请求!)都会创建一个全新的bean。更改输入时,ajax请求会创建一个新bean并设置该值。当您按下按钮时,正常请求会创建一个新bean(因此ajax设置的值会丢失!)并确定该按钮是否有资格被调用 - 这不是 - 因此不会调用该操作。 / p>
视图范围旨在克服这类问题。将bean放在视图范围内。
@ManagedBean
@ViewScoped
public class TheBean {
这样,只要你通过普通或ajax请求与同一个视图交互,bean就会存在。
抱歉,我不知道从正确的CDI声明是什么。它至少被称为“对话范围”。