ข้อความอินพุตภายใน Primefaces dataTable ไม่ได้รับการรีเฟรช

ฉันต้องมี inputTexts อยู่ใน primefaces datatable เมื่อแบบฟอร์มอยู่ในโหมดแก้ไขได้

ทุกอย่างทำงานได้อย่างถูกต้อง ยกเว้นการล้างแบบฟอร์มด้วย Instant="true" (ไม่มีการตรวจสอบความถูกต้องของแบบฟอร์ม) จากนั้น Primefaces DataTable จะทำงานคาดเดาไม่ได้ หลังจากกรอก DataTable ด้วยข้อมูลใหม่แล้ว มันยังคงเก็บค่าเก่าไว้

ตัวอย่างสั้นๆ - เพื่อแสดงความแตกต่างระหว่าง h:dataTable และ p:dataTable - แต่จะทำงานในลักษณะเดียวกันเมื่อมีเพียงหนึ่งในสามตารางจากตัวอย่าง: test.xhtml

<h:body>
    <h:form id="form">

        <p:dataTable var="v" value="#{test.list}" id="testTable">
            <p:column headerText="Test value">
                <p:inputText value="#{v}"/>
            </p:column>
        </p:dataTable>

        <h:dataTable var="v" value="#{test.list}" id="testTable1">
            <h:column>
            <f:facet name="header">
                <h:outputText value="Test value" />
            </f:facet>
                <p:inputText value="#{v}" />
            </h:column>
        </h:dataTable>

        <p:dataTable var="v" value="#{test.list}" id="testTable2">
            <p:column headerText="Test value">
                <h:outputText value="#{v}" />
            </p:column>
        </p:dataTable>

        <p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true" update=":form:testTable :form:testTable1 :form:testTable2"/>
        <p:commandButton value="Update" actionListener="#{test.update()}" update=":form:testTable :form:testTable1 :form:testTable2"/>
    </h:form>
</h:body>

และจาวา:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ViewScoped
public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    private List<String>            list;



    @PostConstruct
    private void init(){
        update();
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void clear() {
        list = new ArrayList<String>();
    }

    public void update() {
        list = new ArrayList<String>();
        list.add("Item 1");
        list.add("Item 2");     
    }
}

ในตัวอย่างข้างต้น ฉันมีการกำหนดค่า 3 แบบ: 1. p:dataTable ด้วย p:inputText 2. h:dataTable ด้วย p:inputText 3. p:dataTable ด้วย h:outputText

และ 2 ปุ่ม: ขั้นแรกล้างข้อมูล ขั้นที่สองใช้ข้อมูล

ขั้นตอนการทำงาน:

  1. ลองเปลี่ยนข้อมูลใน inputTexts ใน p:dataTable และ h:dataTable

  2. ล้างข้อมูลของรายการ (arrayList ของสตริง) - คลิกปุ่ม "ล้าง" (ลองนึกภาพว่าคุณคลิกยกเลิกในแบบฟอร์มเนื่องจากคุณไม่ต้องการเก็บข้อมูลลงในฐานข้อมูล)

  3. โหลดข้อมูลใหม่ - คลิกปุ่ม "อัปเดต" (ลองจินตนาการว่าคุณกำลังเปิดแบบฟอร์มใหม่ด้วยข้อมูลใหม่)

คำถาม: เพราะเหตุใด p:dataTable พร้อมด้วย p:inputText ยังคงจัดเก็บข้อมูลที่เปลี่ยนแปลงด้วยตนเอง ไม่ใช่ข้อมูลที่โหลดไว้ มีวิธีใดบ้างที่จะบังคับให้ p:dataTable ทำงานเหมือน h:dataTable ในกรณีนี้?


person robson    schedule 15.12.2012    source แหล่งที่มา


คำตอบ (2)


วิธีแก้ไขคือ: primefaces resetInput

ในตัวอย่างของฉันมันจะเป็น:

 <p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true"
          update=":form:testTable :form:testTable1 :form:testTable2"> 
    <p:resetInput target=":form:testTable" />
 </p:commandButton>


แก้ไข: ในบางกรณี - หากวิธีการข้างต้นไม่ได้ผล - ลองใช้ส่วนขยายจาก Primefaces:

<pe:resetInput for=":form:testTable" />
person robson    schedule 18.12.2012

ปัญหาที่คุณพบคือเมื่อส่งแบบฟอร์ม ค่า #{test.list} จะถูกส่งสำหรับตารางข้อมูลทุกรายการ (<p> หรือ <h>) ที่เชื่อมโยงกับรายการนี้ในแบบฟอร์ม กล่าวอีกนัยหนึ่ง:

  • JSF จะผูกค่าของ testTable datatable กับ #{test.list} ของคุณ

  • JSF จะผูกค่าของ testTable1 datatable กับ #{test.list} ของคุณ ค่าเหล่านี้จะแทนที่ค่าที่ผูกจาก testTable datatable และข้อมูลจะหายไป #{test.list} จะมีข้อมูลใน testTable1

  • JSF จะผูกค่าของ testTable2 datatable กับ #{test.list} ของคุณ เนื่องจากค่าที่นี่คือ ค่าเก่า ค่าเหล่านี้จึงเป็นค่าที่จะถูกส่งสำหรับ #{test.list}

วิธีที่ดีที่สุดในการแก้ปัญหานี้คือการใช้ <p:dataTable> เดียว (หรือ <h> ขึ้นอยู่กับความต้องการของคุณ) และแอตทริบิวต์ใน Managed Bean ของคุณที่ควบคุมว่าตารางของคุณอยู่ในโหมดดูหรือแก้ไข

รหัส JSF

<h:form id="form">
    <p:dataTable var="v" value="#{test.list}" id="testTable">
        <p:column headerText="Test value">
            <h:outputText value="#{v}" rendered="#{not test.editMode}" />
            <p:inputText value="#{v}" rendered="#{test.editMode}" />
        </p:column>
    </p:dataTable>

    <p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true"
        update="testTable" />
    <p:commandButton value="Update" actionListener="#{test.update()}"
        update="testTable" />
    <!-- adding a new button just for testing purposes -->
    <p:commandButton value="Submit list" action="#{test.submit}" />
</h:form>

รหัส Bean ที่ได้รับการจัดการ

//no need of CDI
@ManagedBean
@ViewScoped
public class Test implements Serializable {

    private List<String> list;
    private boolean editMode = false;

    public Test() {

    }

    @PostConstruct
    private void init(){
        update();
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void clear() {
        list = new ArrayList<String>();
    }

    public void update() {
        list = new ArrayList<String>();
        list.add("Item 1");
        list.add("Item 2");     
    }

    //method for testing purposes
    public void submit() {
        //in real life web apps, you should log the messages, don't use System.out
        System.out.println("Showing actual values of list attribute.");
        for(String s : list) {
            System.out.println(s);
        }
    }
}
person Luiggi Mendoza    schedule 15.12.2012
comment
ขอบคุณ ลุยจิ แต่มันไม่ใช่อย่างที่คุณพูด ฉันโพสต์ตารางทั้งสามนี้เพื่อแสดงความแตกต่างในลักษณะการทำงานของ p:dataTable และ h:dataTable แต่ใส่ตัวอย่างของฉันเพียงตารางเดียวเท่านั้น p:dataTable จะยังคงทำงานตามที่ฉันอธิบายไว้และฉันไม่ชอบ และ h:dataTable จะทำงานตามที่ฉันชอบ คุณช่วยบอกฉันหน่อยได้ไหมว่าทำไม p:dataTable จึงรับรายการว่างที่ถูกผูกไว้จาก bean (หลังจากทำความสะอาด) และต่อมาได้รับการเปลี่ยนแปลงจากมือ แต่ไม่ใช่จากรายการที่ถูกผูกไว้หลังจากสร้างรายการใหม่แล้วและ p:dataTable ได้รับการอัปเดต โดยจะจดจำค่าที่ทำด้วยมือก่อนการล้างรายการใน bean - person robson; 17.12.2012