Java 在请求范围内动态呈现JSF 2内容-在动态内容中未调用侦听器
我把我的问题案例放在下面,这简化了我遇到的一个现实世界的问题。通过将Bean更改为@SessionScoped,我可以解决这个问题,但这确实是不可取的。正如@ViewScoped。我认为它应该在@RequestScoped中工作。我的问题是:Java 在请求范围内动态呈现JSF 2内容-在动态内容中未调用侦听器,java,jsf,jsf-2,java-ee-6,myfaces,Java,Jsf,Jsf 2,Java Ee 6,Myfaces,我把我的问题案例放在下面,这简化了我遇到的一个现实世界的问题。通过将Bean更改为@SessionScoped,我可以解决这个问题,但这确实是不可取的。正如@ViewScoped。我认为它应该在@RequestScoped中工作。我的问题是: 为什么JSF需要访问{simpleBean.outerStrings}来调用{simpleBean.processInnerClick()}侦听器(outerStrings将在上一个请求中失效) 解决这个问题的最佳模式是什么 很高兴编辑,以使更清楚-只
- 为什么JSF需要访问
来调用{simpleBean.outerStrings}
侦听器(outerStrings将在上一个请求中失效){simpleBean.processInnerClick()}
- 解决这个问题的最佳模式是什么
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@RequestScoped
public class SimpleBean implements Serializable {
private List<String> topLevelStrings =
Arrays.asList("TopLevel1", "TopLevel2");
private List<String> outerStrings;
private List<String> innerStrings;
public void processOuterClick() {
System.err.println("processOuterClick()");
outerStrings = Arrays.asList("Outer1", "Outer2", "Outer3");
}
public void processInnerClick() {
System.err.println("processInnerClick()");
innerStrings = Arrays.asList("InnerA", "InnerB", "InnerC");
}
public List<String> getOuterStrings() {
return outerStrings;
}
public List<String> getInnerStrings() {
return innerStrings;
}
public List<String> getTopLevelStrings() {
return topLevelStrings;
}
}
import javax.enterprise.context.requestscope;
导入javax.enterprise.context.SessionScoped;
导入javax.inject.Named;
@命名
@请求范围
公共类SimpleBean实现了可序列化{
私有列表TopLevelString=
数组.asList(“TopLevel1”、“TopLevel2”);
私有列表外串;
私有列表字符串;
public void processOuterClick(){
System.err.println(“processOuterClick()”;
outerString=Arrays.asList(“Outer1”、“Outer2”、“Outer3”);
}
public void processInnerClick(){
System.err.println(“processInnerClick()”;
innerStrings=Arrays.asList(“InnerA”、“InnerB”、“InnerC”);
}
公共列表GetOuterString(){
返回外串;
}
公共列表getInnerStrings(){
返回内部字符串;
}
公共列表GetToLevel字符串(){
返回TopLevelString;
}
}
XHTML
<h:form>
<ui:repeat var="toplevel" value="#{simpleBean.topLevelStrings}"
id="toplevel_id">
<h:commandLink id="toplevel_command">
#{toplevel} <br/>
<f:ajax render="outerlevel_panel"
listener="#{simpleBean.processOuterClick()}"/>
</h:commandLink>
<h:panelGroup id="outerlevel_panel">
<ui:repeat var="outerLevel" value="#{simpleBean.outerStrings}"
id="outerlevel_id">
<h:commandLink id="outerlevel_command">
#{outerLevel} <br/>
<f:ajax listener="#{simpleBean.processInnerClick()}" render="innerlevel_panel"/>
</h:commandLink>
<h:panelGroup id="innerlevel_panel">
<ui:repeat var="innerLevel" value="#{simpleBean.innerStrings}"
id="innerlevel_id">
<h:commandLink id="innerlevel_command">
#{innerLevel} <br/>
</h:commandLink>
</ui:repeat>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</ui:repeat>
</h:form>
#{toplevel}
#{outerLevel}
#{innerLevel}
基本上:
侦听器触发ok,并呈现#{outerLevel}命令链接#{simpleBean.processOuterClick()}
- 但是,当我单击
命令链接时,{outerLevel}
侦听器从未被触发{simpleBean.processInnerClick()}
@ViewScoped
你只需要管理对话的开始和结束
另见:
来传递请求参数,并在(post)构造函数中准确地准备所需的模型。也看到了哦,好的,我看到了。谢谢我认为jsf不太适合这样的问题——它有组件树,我只想渲染一个新组件,而不是检查渲染原始视图时使用的模型数据是否仍然存在。最终的结果是,我只想在DOM中保存的数据必须比我想在服务器上保存的时间长。在基于动作的框架中,我将使用Ajax调用服务器,评估JSP并将输出发送回。然后,我会将内容附加到dom元素中。对于我的需求,这正是我想要jsf做的——我不希望Ajax调用需要之前使用的服务器上的整个数据集
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class SimpleBean implements Serializable {
// ...
}
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
@Named
@ConversationScoped
public class SimpleBean implements Serializable {
@Inject
private Conversation conversation;
@PostConstruct
public void init() {
conversation.begin();
}
public String navigateToOtherPage() {
conversation.end();
return "otherPage?faces-redirect=true";
}
// ...
}