【发布时间】:2016-01-05 16:00:15
【问题描述】:
更新:
任何@ViewScoped 和@SessionScoped bean 的生命周期都不是预期的。也就是说,它们的结束时间比应有的要早。例如,当方法返回 void 的 ajax 回发完成时,@ViewScoped 或 @SessionScoped bean 都不应该结束,但它们会结束。
在将它部署到我们的开发环境和其他人对其进行测试之后,它似乎只发生在我的机器上并且在本地运行时发生。不知道为什么。 tc Server 3.1 正在使用。
我将保留原件,以防有人遇到类似问题。
原文:
我有一棵由 ViewScoped 填充的树,它从 XML 文件中读取数据并为其创建 TreeNode 对象。性能不是超级快,因此在视图中创建一次是理想的。 (下面省略了一些代码,但功能确实有效)
@ManagedBean
@ViewScoped
public class FundsXmlTreeBuilder implements Serializable {
private TreeNode root;
public FundsXmlTreeBuilder() throws SAXException, IOException, ParserConfigurationException {
root = new DefaultTreeNode("Root", null);
buildTree();
}
public void buildTree() throws SAXException, IOException, ParserConfigurationException {
//reads xml file and adds TreeNodes
}
}
还有另一个 RequestScoped bean,它有一个方法来处理在 onNodeSelect 方法中被选中的树节点的 ajax 事件。它基本上决定了页面的另一部分将如何显示。
@ManagedBean
@RequestScoped
public class FundsXmlDisplay implements Serializable{
private Fund fund;
private FundFamily fundFamily;
private FocusedPortfolioModel model;
public TreeNode selectedRoot;
public FundsXmlDisplay() {
fund = null;
fundFamily = null;
model = null;
selectedRoot = null;
}
public void onNodeSelect(NodeSelectEvent event) {
Object data = event.getTreeNode().getData();
fund = null;
fundFamily = null;
model = null;
if (data instanceof Fund) {
fund = (Fund) data;
} else if (data instanceof FundFamily) {
fundFamily = (FundFamily) data;
} else if (data instanceof FocusedPortfolioModel) {
model = (FocusedPortfolioModel) data;
model.createPieModel();
}
}
}
这里是标记的主要部分。
<h:body>
<h:form styleClass="form" id="form1">
*** For Home Office Use Only
<br />
<p:layout id="xmlArea"
style="min-width:400px;min-height:600px;width:95%;">
<p:layoutUnit id="xmlTree" position="west" resizable="false"
closable="false" scrollable="true" size="25%" minSize="40"
maxSize="400" style="padding:.25em;" header="Funds XML Elements">
<p:tree value="#{fundsXmlTreeBuilder.root}" var="node"
dynamic="false" selectionMode="single">
<p:ajax event="select" update=":form1:xmlDisplay"
listener="#{fundsXmlDisplay.onNodeSelect}" />
<p:treeNode>
<h:outputText value="#{node}" style="font-size:small" />
</p:treeNode>
</p:tree>
</p:layoutUnit>
<p:layoutUnit position="center" header="Element Detail" size="75%">
<p:scrollPanel id="xmlDisplay" mode="native"
style="height:100%;">
...
</p:scrollPanel>
</p:layoutUnit>
</p:layout>
</h:form>
</h:body>
我遇到的问题是 FundsXmlTreeBuilder 在 ajax 事件被触发之后但在侦听器之前重新创建。我希望它根本不会被重新创建,因为据我了解,视图没有改变。
xmlDisplay 区域中有不少渲染属性。不确定这是否相关。我知道当操作方法返回 null 或 void 时视图存在,但我不认为正在使用的呈现方法算作“操作方法”。
还有什么有趣的,如果我将 FundsXmlTreebuilder 更改为 SessionScoped,它也会在选择一个节点后重新创建,这确实让我感到难过。
希望一切都清楚,并提供足够的信息。谢谢!
【问题讨论】:
-
正在重新创建的有问题的 bean 是 FundsXmlDisplay,对吧?
-
应该指定。 FundsXmlTreeBuilder 是在我不希望它重新创建的时候(在 ajax 事件之后,但在执行侦听器之前)。我将编辑问题以使其更清楚。
-
你能用普通的旧 div 和 css 替换 layout 和 layoutUnits 看看会发生什么吗?
-
围绕布局的表单并不是最好的设计。并且**不要在构造函数中做任何工作,使用
@PostConstruct注释方法。在SO中搜索重复,存在
标签: jsf jsf-2 view-scope session-scope tcserver