本文介绍了访问p:datatable列表中的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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 =更新action =#{events.regUpdateAll()}
process =@ formupdate =@ form/>

< div style =float:right>
< p:selectOneButton rendered =#{events.selectedEvent.noOfRounds gt 0}value =#{events.activeRoundIndex}>
< f:selectItem itemLabel =1itemValue =0/>
< f:selectItem itemDisabled =#{events.selectedEvent.noOfRounds lt 2}itemLabel =2itemValue =1/>
< f:selectItem itemDisabled =#{events.selectedEvent.noOfRounds lt 3}itemLabel =3itemValue =2/>
< f:selectItem itemDisabled =#{events.selectedEvent.noOfRounds lt 4}itemLabel =4itemValue =3/>
< f:ajax execute =@ formrender =@ form/>
< / p:selectOneButton>
< / div>
< p:dataTable value =#{events.registrationList}var =itemrowIndexVar =rowIndex>
< p:columnGroup type =header>
< p:row>
< p:column headerText =First Namerowspan =2/>
< p:column headerText =Last Namerowspan =2/>
< p:column headerText =Round#{i + 1}colspan =2/>
< / p:row>
< p:row>
< p:column headerText =Tee Time/>
< p:column headerText =起始孔/>
< / 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 =timetimeStyle =short/>< / p:inputText>
< / p:column>
< p:column>
< p:inputText value =#{item.roundList.get(i).startingHole}/>
< / p:column>
< / p:dataTable>

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



任何方向将不胜感激



BTW这个问题是重写的,因为我无法弄清格式化放小代码片段。



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

public ItemHolder(){
name =Test;
items = new ArrayList();
items.add(new Item(index 0,0,0));
items.add(new Item(index 1,1,1));
}
// getter和setter

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和Setters

任何帮助非常感谢如果是系统错误,解决方法的任何建议也将有所帮助。我没有想法。



谢谢约翰

解决方案

c:forEach c:set 正在引发您的问题。请参阅 在)



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

我没有检查,但我打赌阶段4总是更新最后一个可用的('minor') sub.p1 。这是因为在第4阶段运行时, sub (last'minor')是一个常量,因为它在每个 c:forEach






  • 不要使用 c:标签。

  • 而不是 c:forEach 使用 ui:重复

  • 而不是 c:set ,use完整路径#{item2.items.get(test.selectedIndex).p1} 。 (可能需要重构基础数据结构)


  • I have a pojo list within a pojo list that I am trying to use in a dynamic way in a data table with jsf 2.2.6 and primefaces 4.0. I think I am close but I haven't been able to make it work.

    The idea is to configure multiple rounds of a golf competition. Main list (registrations) is all players with info like name, handicap factor, etc. The List within the registration list is tee times, start hole, etc per round where it could be anywhere from 1-4 rounds and I only want to display one at a time in columns of the p:dataTable. The user would click the round they want to see, using the selectOneButton and it would dynamically change to that data.

    The key ideas are (1) selectOneButton and ajax to trigger the change of a property identifying the index to the table. (2) JSTL to help make the EL expressions shorter and more readable (3) Typical datatable to walk through the primary list (4) EL putting it all together to try and extract the right round based on the index chosen by the button.This is a stripped down version to show the problem but I don't think I have left out anything important. Here is the 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>
    

    There are no crashes and the data is formatted correctly, just not retrieved from the correct location

    Any direction would be greatly appreciated

    BTW this question was re-written as I was unable to figure out the formatting to put smaller code snippets.

    UPDATE: have proven the concept in another area of my code and diagnosed the problem further. The Update Model Values phase (4) is updating the wrong index in my list. i.e. if I am viewing hole 1 (index 0) and click for hole 2 it actually updates properties at index 1 rather than 0 in JSF phase 4 (Mojara). I think this could only occur due to the code shown above. Can anyone see what I am doing wrong or is it a system bug?

    Further update with a complete and simple code example demonstrating the problem. By making P1 editable and P2 display you can see that the property is changed without user input. I believe it is a system bug but hope I am wrong as I really need this to work. Here is the code:

        <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>
    

    and the SessionScoped JAVA code

    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
    

    Any help would be greatly appreciated. If it is a system bug any suggestions for a workaround would also be helpful. I'm running out of ideas.

    Thanks, John

    解决方案

    The c:forEach and c:set are causing your problems. See various articles on the subject. (also see BalusC's comment)

    Basically, the c: tags do not save state (not part of the jsf component tree) and are causing what you noted:

    I didn't check, but I bet phase 4 is always updating the last available ('minor') sub.p1. This is because by the time phase 4 runs, sub (last 'minor') is a constant because it's state during each c:forEach iteration is not saved in the component tree.

    Suggestions?

    • Don't use c: tags.
    • Instead of c:forEach use ui:repeat
    • instead of c:set, use the full path #{item2.items.get(test.selectedIndex).p1}. (maybe a restructuring of the underlying data structures is needed)

    这篇关于访问p:datatable列表中的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-18 17:33