2014-04-26 27 views
2

我在pojo列表中有一个pojo列表,我试图在jsf 2.2.6和primefaces 4.0的数据表中以动态方式使用pojo列表。我认为我很接近,但是我一直无法完成工作。访问p:datatable列表中的列表

这个想法是配置多轮高尔夫比赛。主要名单(注册)是所有有名字,障碍因素等信息的球员。注册名单内的名单是开球次数,开球次数等,每轮可以是1-4轮,我只想显示一次一个在p:dataTable的列中。用户将使用selectOneButton单击他们想要查看的轮,并且它会动态更改为该数据。

关键思想是(1)selectOneButton和ajax来触发标识索引到表的属性的更改。 (2)JSTL帮助使EL表达式变得更短并且更易读(3)典型的数据表遍历主表(4)EL把它放在一起,试图根据按钮选择的索引提取右轮。 这是一个精简版,以显示问题,但我不认为我已经遗漏了任何重要的东西。这里是XHTML:

<c:set value="#{events.activeRoundIndex}" var="i"/> 

<p:commandButton value="Update" action="#{events.regUpdateAll()}" 
       process="@form" update="@form" /> 

<div style="float: right"> 
    <p:selectOneButton rendered="#{events.selectedEvent.noOfRounds gt 0}" value="#{events.activeRoundIndex}"> 
     <f:selectItem itemLabel="1" itemValue="0"/> 
     <f:selectItem itemDisabled="#{events.selectedEvent.noOfRounds lt 2}" itemLabel="2" itemValue="1"/> 
     <f:selectItem itemDisabled="#{events.selectedEvent.noOfRounds lt 3}" itemLabel="3" itemValue="2"/> 
     <f:selectItem itemDisabled="#{events.selectedEvent.noOfRounds lt 4}" itemLabel="4" itemValue="3"/> 
     <f:ajax execute="@form" render="@form"/> 
    </p:selectOneButton> 
</div> 
<p:dataTable value="#{events.registrationList}" var="item" rowIndexVar="rowIndex"> 
    <p:columnGroup type="header"> 
     <p:row> 
      <p:column headerText="First Name" rowspan="2"/> 
      <p:column headerText="Last Name" rowspan="2"/> 
      <p:column headerText="Round #{i+1}" colspan="2"/> 
     </p:row> 
     <p:row> 
      <p:column headerText="Tee Time"/> 
      <p:column headerText="Start Hole"/> 
     </p:row> 
    </p:columnGroup> 

    <p:column>#{item.playerId.firstName}</p:column> 
    <p:column>#{item.playerId.lastName}</p:column> 
    <p:column> 
     <p:inputText value="#{item.roundList.get(i).teeTime}"> 
      <f:convertDateTime type="time" timeStyle="short"/></p:inputText> 
    </p:column> 
    <p:column> 
     <p:inputText value="#{item.roundList.get(i).startingHole}"/> 
    </p:column> 
</p:dataTable> 

没有崩溃,数据格式正确,只是没有从正确的位置检索

任何方向将不胜感激

BTW这个问题是重写我无法找出格式化,以放置较小的代码片段。

更新:已经在我的代码的另一个领域证明了这个概念,并进一步诊断出这个问题。更新模型值阶段(4)正在更新列表中的错误索引。即如果我正在查看洞1(索引0)并单击孔2,它实际上会更新索引1处的属性,而不是JSF阶段4(莫哈拉)中的0。我认为这可能只是由于上面显示的代码。任何人都可以看到我做错了什么,或者它是一个系统错误?

用一个完整而简单的代码示例演示问题的进一步更新。通过使P1可编辑和P2显示,您可以看到该属性在没有用户输入的情况下被更改。我相信这是一个系统错误,但希望我错了,因为我真的需要这个工作。下面是代码:

<p:panelGrid> 
     <p:row> 
      <p:column>Name</p:column> 
      <p:column>Selected Index</p:column> 
      <p:column>P1</p:column> 
      <p:column>P2</p:column> 
     </p:row> 

     <c:forEach items="#{test.list}" var="item2"> 
      <c:set value="#{test.getMinor(item2)}" var="sub"/> 
      <p:row> 
       <p:column>#{item2.name}</p:column> 
       <p:column>#{test.selectedIndex}</p:column> 
       <p:column><p:inputText value="#{sub.p1}"/></p:column> 
       <p:column>#{sub.p2}</p:column> 
      </p:row> 
     </c:forEach> 
    </p:panelGrid> 
</h:form> 

和SessionScoped JAVA代码

public class Test { 

private List<ItemHolder> list; 
private int selectedIndex=0; 

public Test() { 
    list = new ArrayList(); 
    list.add(new ItemHolder()); 
} 

public void doNothingAjax() { 
} 

public Item getMinor(ItemHolder holder) { 
    return holder.getItems().get(selectedIndex); 
} 
//Getters & Setters 

public class ItemHolder { 

    private String name; 
    List<Item> items; 

    public ItemHolder() { 
     name = "Test"; 
     items = new ArrayList(); 
     items.add(new Item("index 0",0,0)); 
     items.add(new Item("index 1",1,1));    
    } 
    //getters and setters 

public class Item { 
    private String label; 
    private int p1; //property 1 
    private int p2; //property 2 

    public Item(String label, int p1, int p2) { 
     this.label = label; 
     this.p1 = p1; 
     this.p2 = p2; 
    } 

    //Getters and Setters 

任何帮助将不胜感激。如果这是一个系统错误,对于解决方法的任何建议也会有所帮助。我正在用尽想法。

谢谢,约翰

+0

在这个问题中''的代码是否丢失? – Omar

+0

我不知道我做了什么奥马尔,但我有那里的文字,但格式化搞砸了。我认为修订版本会更清晰。 – GolfAddict

+0

我遵循链接和你的建议,倾向于使用ui:组件,而不是使用jstl,这对现在我更了解它们是有道理的。感谢那!我不认为他们是这个问题的原因,虽然......第一个例子只是使用p:dataTable,我没有直接访问属性,没有c:set。结果是一样的。我后来建立了一个特定的视图来解决这个问题,但我更喜欢不必为了使UI工作而构建自定义结构。 – GolfAddict

回答

2

c:forEachc:set是造成你的问题。请参阅subject上的variousarticles。(见BalusC's comment

基本上,c:标签不保存状态(不JSF组件树的一部分),是造成你注意什么:

更新模型值阶段(4)更新我的清单中有错误的索引。

我没有检查,但我打赌第4阶段总是更新最后可用('次要')sub.p1。这是因为在阶段4运行时,sub(last'minor')是一个常量,因为它在每个阶段的状态为c:forEach,迭代没有保存在组件树中。

对此提出建议?

  • 请勿使用c:标签。
  • 而不是c:forEach使用ui:repeat
  • 代替c:set,使用完整路径#{item2.items.get(test.selectedIndex).p1}。 (可能需要重新构建底层数据结构)