【问题标题】:accessing a list within a list in p:datatable访问 p:datatable 中列表中的列表
【发布时间】:2014-06-12 13:18:24
【问题描述】:

我在 pojo 列表中有一个 pojo 列表,我试图在 jsf 2.2.6 和 primefaces 4.0 的数据表中以动态方式使用它。我想我已经接近了,但我无法让它发挥作用。

这个想法是配置多轮高尔夫比赛。主名单(注册)是所有球员的姓名、差点因素等信息。注册名单中的名单是每轮的开球时间、开始洞等,可能是 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>

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

任何方向都将不胜感激

顺便说一句,这个问题被重新编写,因为我无法弄清楚放置更小的代码 sn-ps 的格式。

更新:已经在我的代码的另一个领域证明了这个概念,并进一步诊断了问题。更新模型值阶段 (4) 正在更新我列表中的错误索引。即,如果我正在查看孔 1(索引 0)并单击孔 2,它实际上会更新索引 1 处的属性,而不是 JSF 阶段 4(Mojara)中的 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

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

谢谢,约翰

【问题讨论】:

  • 问题中是否缺少&lt;p:dataTable&gt;的代码?!
  • 我不确定我做了什么奥马尔,但我有文字,但格式搞砸了。我觉得修改后的版本会更清晰。
  • 我按照链接和您的建议支持 ui: components over jstl,现在我对它们有了更好的理解,这很有意义。感谢那!我不认为他们是这个问题的原因......第一个例子只是使用了p:dataTable,我确实尝试在没有c:set的情况下直接访问该属性。结果是一样的。我随后构建了一个特定的视图来克服这个工作正常的问题,但我更喜欢不必为了使 UI 工作而构建自定义结构。

标签: jsf jsf-2 primefaces datatable


【解决方案1】:

c:forEach 和 c:set 导致了您的问题。请参阅 subject 上的 various articles。 (另见BalusC's comment)

基本上,c: 标记不保存状态(不是 jsf 组件树的一部分)并导致您注意到:

更新模型值阶段 (4) 正在更新我列表中的错误索引。

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

建议?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-05
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    相关资源
    最近更新 更多