ui:在o:tree中重复,没有按预期工作



我使用的是"分支"的泛面o:树,其中每个分支都有一个"叶子列表",属性为"颜色",应该在树中可编辑。

- branch 0
  - leaf 0 (color = "green")
  - leaf 1 (color = "yellow")
- branch 1
  - leaf 0 (color = "purple")
  - branch 1_0
    - leaf 1 (color = "red")
    - leaf 2 (color = "orange")
    - leaf 3 (color = "brown")

添加/移除树枝和在任何树枝上添加树叶效果良好,符合预期。此外,对包括所有叶子列表的任何复杂树的渲染(显示具有正确值的颜色属性)都像魔术一样工作。

但是更改颜色或移除叶(因此ui:repeat中的任何内容)只能按预期用于最后渲染的分支

其他叶/分支的"颜色"输入字段根本不起作用,ui:repeat中的删除叶链接也不起作用。对于removeLaf(…)中的叶属性,总是传递上一个渲染分支中的相应叶。因此,在上面的示例中,单击从分支0删除yellow叶将调用removeLeaf(orange,分支0),然后它将不会删除任何内容,因为分支0没有橙色叶。

这是绑定到关键部分的代码-如果需要,还可以提供其他任何东西:

<h:form>
  <o:tree value="#{treeBean.tree}" var="branchEntity" varNode="branchNode">
    <o:treeNode>
      <o:treeNodeItem>
        <ui:repeat value="#{branchEntity.leafList}" var="leaf">
          <h:panelGrid columns="2">     
            <p:inputText value="#{leaf.color}" />   
            <p:commandLink action="#{treeBean.removeLeaf(leaf, branchEntity)}" styleClass="ui-icon ui-icon-trash"
                        process="@form" update="@form" />               
          </h:panelGrid>
        </ui:repeat>    
        <p:commandLink action="#{treeBean.addLeaf(branchEntity)}" styleClass="ui-icon ui-icon-plus"
                process="@form" update="@form" />
        <o:treeInsertChildren />
      </o:treeNodeItem>
    </o:treeNode>
  </o:tree>
  <p:commandButton id="save" value="Save" action="#{treeBean.save}" process="@form" update="@form" />
</h:form>

我知道嵌套的ui:repeat有一些问题,但由于我在Mojarra 2.1.19上,我想这里的情况并非如此。如果我用一个在分支列表上迭代的ui:repeat替换o:tree,那么实际上嵌套两个ui:repeats是很好的。但后来我显然失去了我需要的树功能。我刚刚测试了这一点,以验证嵌套的ui:repeat是否正常工作。

这个问题似乎与另一个问题类似,但并不完全相同。。。

如果我用p:dataList替换内部的ui:repeat(如解决ui:repeat问题的其他一些答案中所建议的,以及现在这里的BalusC答案中的建议),removeLeaf()链接将全部正常工作,但仍然只有最后一个分支的颜色输入字段将被绑定。

更新:我现在在使用p:dataList时仔细查看了一下。我从浏览器开发工具获得的AJAX请求中的POST内容看起来不错:

javax.faces.partial.ajax=true
javax.faces.source=hForm:save
javax.faces.partial.execute=hForm
javax.faces.partial.render=hForm
hForm:save=hForm:save
hForm=hForm
hForm:oTree:0:pDataList:0:color=green
hForm:oTree:0:pDataList:1:color=yellow
hForm:oTree:1:pDataList:0:color=purple
hForm:oTree:1_0:pDataList:0:color=red
hForm:oTree:1_0:pDataList:1:color=orange
hForm:oTree:1_0:pDataList:2:color=brown
javax.faces.ViewState=-6137230173999059936:-6718691551411872927

treeBean.save()方法只是将整个Tree.toString()记录到控制台,结果如下:

[Branch [leafList=[Leaf [color=null], Leaf [color=null]]],
Branch [leafList=[Leaf [color=null]]]
[Branch [leafList=[Leaf [color=red], Leaf [color=orange], Leaf [color=brown]]]]]

如果颜色有价值!=null之前,该值保持不变,因此不会被null覆盖。我对JSF还不够深入,不知道如何调查信息在途中丢失的地方。

(我最初在JBoss EAP 6.2+Primefaces 5.2+Omnifaces 2.1上使用了Mojarra 2.1.19,但在Mojara 2.2.12、TomEE、Primeffaces 5.3+Omnifaces 2.2上也体验到了完全相同的体验。完整的Maven Eclipse示例项目可以在这里找到。我甚至直接向Branch添加了一个更简单的String属性(没有List),效果很好。)

这确实是由<ui:repeat>中的状态管理错误引起的。它没有正确地识别出自己嵌套在另一个迭代器中,并在父迭代器的每次迭代中重新访问之前顽固地清除状态。它只识别父UIRepeatUIData,但仅此而已。<o:tree>没有也不能从UIData扩展,不幸的是,UIRepeat是一个特定于实现的类,因此只要你想独立于特定的JSF实现(Mojarra、MyFaces等),就不能公开使用。

最好的办法是用一个真正的UIData组件来代替<ui:repeat>,它具有更好的状态管理实现。我刚刚在这里尝试过,添加项目对我使用<h:dataTable><p:dataList>来说很好。由于<h:dataTable>提供了错误的客户端ID,仅删除项目失败。它没有考虑容器客户端ID。<p:dataList>在添加和删除项目的两种情况下都对我有效。仍然更新列表中任何绑定输入字段的服务器端模型失败,如本答案评论中详细讨论的那样。

<p:dataList type="none">替换整个<ui:repeat>(如果没有type,它将呈现<ul><li>)是最接近的。

<p:dataList type="none" value="#{branchEntity.leafList}" var="leaf">
    ...
</p:dataList>

如果JSF提供了一个类似UIRepeat的公共(标记)接口,所有中继器在管理状态时都可以检查这个接口,那么世界就会简单得多。

相关内容

  • 没有找到相关文章

最新更新