【问题标题】:JSF refreshing list via Ajax incorrectlyJSF 通过 Ajax 刷新列表不正确
【发布时间】: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 太失败了。那么如何更新循环打印的一组元素的页面部分呢?

标签: jsf-2 jsf-2.2


【解决方案1】:

显然是well-known thing 我的结构不能在JSF 中动态更新。我必须做出的解决方案是使用h:datatable 而不是&lt;ul&gt; 列表(这是我非常不喜欢JSF 的一件事,但我不确定如何使用基本JSF 来render a list - 而不是表格,我可以动态更新。

Ajax render 属性必须指定 form id。

<h:form id="visor">
      <h:dataTable value="#{controller.list}" var="element">
                    <h:column>
                        ....
                        <h:commandButton action=.... >
                          <f:ajax render="visor" execute="@this" />
                        </h:commandButton>
                        ....
                    </h:column>
      </h:dataTable>
</h:form>

编辑UL 也可以,只要我渲染表单并且表单包含所有内容

【讨论】:

  • 我使用 ui:repeat 来处理类似的事情(iirc),不知道为什么它不适合你。将尝试看看是什么让这个案例实际上不起作用......在“众所周知的事情”帖子中,你看到海报使用c:for-each,并且建议使用ui:repeat作为外循环。 ..所以我今晚会检查...
  • 老实说,我不确定问题是否出在form 所在的位置,以及render 使用了哪个ID。我还需要创建一个结构,如:&lt;nav&gt; &lt;ul&gt; &lt;li&gt;&lt;a ...&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/nav&gt;,我不能为此使用datatable。所以我尝试了一个列表和ui:repeat,它似乎在那个地方工作 - 所以我很困惑。我会做更多的测试
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 2015-06-15
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多