【发布时间】:2018-11-17 09:28:24
【问题描述】:
我正在尝试将一些功能从 JQuery 迁移到 JSF,但结果很奇怪。
基本上,它是一个可以导航链接的页面(想象一下,就像 Web 上的 Windows 资源管理器)。文件夹有链接,叶子没有。为了构建它,它使用了private List<Element> list;,它会相应地刷新。因此,当用户单击“文件夹”时,会使用该文件夹的内容创建一个新的list。
问题是我得到了奇怪的结果。有时我浏览一个链接并且它被正确刷新,但在某些情况下它的行为就像页面被重新加载(但它不是)并且list被重置为其初始值(?)。例如,我导航到“name2”并得到正确的东西。但后来我转到“name2b”,而不是叶子,我得到“name1”、“name2”和“name3”,它们只在init() 方法中设置。我不知道这是怎么发生的,但是探索源代码似乎c:foreach 结构与 id 混淆,并且页面中呈现了旧 ID(请注意,我尝试过 ui:repeat 具有相同的错误结果) .
我该如何解决这个问题?
这是简化的代码:
<f:metadata>
<f:viewAction action="#{controller.init}" />
</f:metadata>
...
<h:panelGroup id="visor" layout="block">
<ul>
<c:forEach items="#{controller.list}" var="element">
<li>
<ui:fragment rendered="#{element.folder}">
<h:form>
<h:commandButton action="#{controller.navigate(element.name)}" type="submit" value="#{element.name}" >
<f:ajax render="visor" execute="@this" />
</h:commandButton>
</h:form>
</ui:fragment>
<ui:fragment rendered="#{not element.folder}">
<span>#{element.name}</span>
</ui:fragment>
</li>
</c:forEach>
</ul>
</h:panelGroup>
还有控制器
@Named(value = "controller")
@ViewScoped
public class MyController implements Serializable {
private List<Element> list;
public void init() { //Called when loading the page
list = new ArrayList<>();
Element e1 = new Element("name1", true); //name and isFolder?
Element e2 = new Element("name2", true);
Element e3 = new Element("name3", true);
list.add(e1);
list.add(e2);
list.add(e3);
}
public void navigate(String name) {
list = new ArrayList<>();
if (name.equals("name1")) {
Element e1 = new Element("name1a", true);
Element e2 = new Element("name1b", true);
Element e3 = new Element("name1c", true);
list.add(e1); list.add(e2); list.add(e3);
} else if (name.equals("name2")) {
Element e1 = new Element("name2a", true);
Element e2 = new Element("name2b", true);
Element e3 = new Element("name2c", true);
list.add(e1); list.add(e2); list.add(e3);
} else {
Element e1 = new Element("leaf1", false);
Element e2 = new Element("leaf2", false);
list.add(e1); list.add(e2);
}
}
//....
编辑
我的问题似乎描述为in here。
我必须调查this question 是否可以为这个主题带来一些启示。
【问题讨论】:
-
首先不在命令按钮上执行
type="submit"。以及如何以及何时调用 init?它不应该只是一个@PostConstruct带注释的方法吗?请尝试创建minimal reproducible example,而不是让我们猜测。哦,检查showcase.omnifaces.org/components/tree,可能很有趣还有debug...检查事情是否被意外调用... -
不是
submit的原因是什么?我在其他地方也这样做过,而且效果一直很好。我将更新 init()。我也调试过,调用都是正确的,列表的 size() 也是。但是当我收到错误时,没有调用“navigate()” -
1:它是“默认”,2:结合 ajax 我有时会看到一些奇怪的东西(jsf c:foreach 更新页面。那是行不通的。您无法更新通过 c:foreach 呈现的部分...请参阅stackoverflow.com/questions/3342984/…(阅读 JSF 上的所有 >25 点赞 Q/A 并记住它们的存在以备不时之需......真的很有帮助。或者从 jsf.zeef.com 开始
-
感谢您的 cmets。我过去读过那篇文章,这是有道理的,尽管正如我在问题中所说的那样,我尝试
ui:repeat太失败了。那么如何更新循环打印的一组元素的页面部分呢?