gpt4 book ai didi

java - 在请求范围内动态呈现 JSF 2 内容 - 在动态内容中时不会调用监听器

转载 作者:行者123 更新时间:2023-11-30 04:54:46 25 4
gpt4 key购买 nike

我已将我的问题案例放在下面,这简化了我遇到的现实问题。通过将 Bean 更改为 @SessionScoped 我可以解决这个问题,但这确实是不可取的。 @ViewScoped 也是如此。我认为它应该在@RequestScoped 中工作。我的问题是:

  • 为什么 JSF 需要访问 #{simpleBean.outerStrings} 来调用 #{simpleBean.processInnerClick()} 监听器(outerStrings 将在上一个请求中死亡) )
  • 解决这个问题的最佳模式是什么?

很高兴进行编辑以使其更加清晰 - 请告诉我。

Bean类

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;
}

}

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>

基本上:

  • #{simpleBean.processOuterClick()} 监听器正常触发,并且 #{outerLevel} 命令链接呈现
  • 但是当我单击 #{outerLevel} 命令链接时,#{simpleBean.processInnerClick()} 监听器永远不会触发

最佳答案

对于此特定要求,请求范围是错误的范围。请求范围的 bean 在响应结束时将被垃圾化,并且将在后续请求中创建一个新的 bean,并将其所有属性设置为默认值。用 JSF2 术语来说,您确实需要 View 范围。 session 范围确实太宽泛了,并且对于这一要求来说比请求范围更糟糕(当最终用户在多个窗口/选项卡中打开同一页面时,他们将在物理上共享同一个 bean,从而导致每次 View 行为不直观)最终用户在交互后在 View 之间切换)。

要解决您的特定问题,您所需要做的就是使用 @ManagedBean @ViewScoped :

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class SimpleBean implements Serializable {
// ...
}

由于某种原因,您似乎更喜欢 CDI 管理而不是 JSF 管理,因此 @ViewScoped 的 CDI 替代方案是 @ConversationScoped .

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";
}

// ...
}

您只需管理对话的开始和结束 yourself .

另请参阅:

关于java - 在请求范围内动态呈现 JSF 2 内容 - 在动态内容中时不会调用监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8883551/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com