首页 文章

Primefaces dataTable中的InputText不会刷新

提问于
浏览
0

当窗体处于可编辑模式时,我需要在primefaces数据表中包含inputTexts .

一切正常,除了使用immediate =“true”进行清理(没有表单验证) . 然后,primefaces数据表的行为是不可预测的 . 在使用新数据填充数据表后 - 它仍然存储旧值 .

简短示例 - 显示h:dataTable和p:dataTable之间的差异 - but it works the same way when there is only one of three tables from the example :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>

和java:

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 with p:inputText 2. h:dataTable with p:inputText 3. p:dataTable with h:outputText

2个按钮:首先清除数据,第二个应用数据

工作流程:

  • 尝试更改p:dataTable和h:dataTable中inputTexts中的数据

  • 清除列表数据(字符串的数组列表) - 单击“清除”按钮(假设您单击表单上的取消,因为您不想将数据存储到数据库)

  • 加载新数据 - 点击“更新”按钮(假设您正在使用新数据打开新表单)

Question: 为什么p:dataTable with p:inputText仍然存储手动更改的数据,而不是已加载的数据?有没有办法强制p:dataTable在这种情况下表现得像h:dataTable?

2 回答

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

    EDIT: 在某些情况下 - 如果上述方法不起作用 - 请尝试使用primefaces扩展中的一个:

    <pe:resetInput for=":form:testTable" />
    
  • 5

    您遇到的问题是,在提交表单时,会为表单中此列表绑定的每个数据表( <p><h> )提交 #{test.list} 值 . 换一种说法:

    • JSF会将 testTable 数据表的值绑定到 #{test.list} .

    • JSF会将 testTable1 数据表的值绑定到 #{test.list} . 这些值将替换 testTable datatable中绑定的值,并且数据将丢失 . #{test.list} 将包含 testTable1 中的数据 .

    • JSF会将 testTable2 数据表的值绑定到 #{test.list} . 由于此处的值是旧值,因此这些值将是 #{test.list} 将提交的值 .

    解决此问题的最佳方法是使用单个 <p:dataTable> (或 <h> ,具体取决于您的需要)以及托管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);
            }
        }
    }
    

相关问题