Подтвердить что ты не робот

Обновление целых <p: dataTable> по завершении <p: ajax event = "cellEdit" >

У меня возникли трудности с повторной рендерингом PrimeFaces Datatable после редактирования ячейки. Изменение значения в одной ячейке может изменить записи в других ячейках, следовательно, необходимо обновить всю таблицу.

Здесь страница JSF:

<h:form id="testForm">
    <p:outputPanel id="testContainer">

        <p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">

            <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />

            <p:column headerText="Col1">  
                <p:cellEditor>
                    <f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet>
                    <f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet>
                </p:cellEditor> 
            </p:column>

            <p:column headerText="Col2">
                <p:cellEditor>
                    <f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet>
                    <f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet>
                </p:cellEditor>  
            </p:column>

        </p:dataTable>

        <p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />

    </p:outputPanel>                                    
</h:form>

И здесь поддержка bean:

@ManagedBean(name = "tableBean", eager = false)
@ViewScoped 
public class TableBean {

    public TableBean() {
        RowData entry = new RowData("a1", "b1");
        entries.add(entry);
        entry = new RowData("a2", "b2");
        entries.add(entry);
        entry = new RowData("a3", "b3");
        entries.add(entry);
    }

    public class RowData {

        private String col1;
        private String col2;

        public RowData(String col1, String col2) {
            this.col1 = col1;
            this.col2 = col2;
        }

        public String getCol1() {
            return col1;
        }

        public void setCol1(String col1) {
            this.col1 = col1;
        }

        public String getCol2() {
            return col2;
        }

        public void setCol2(String col2) {
            this.col2 = col2;
        }
    }

    private ArrayList<RowData> entries = new ArrayList<RowData>();

    public List<RowData> getData() {
        return entries;
    }

    public void onCellEdit(CellEditEvent event) {
        entries.get(event.getRowIndex()).setCol1("Dummy Col 1");
        entries.get(event.getRowIndex()).setCol2("Dummy Col 2");        
    }   
}

При включении update = ": testForm: testContainer" в событие cellEdit AJAX, изменение значения ячейки удаляет данные на экране и только отображает содержимое ячейки (вместе с кнопкой) - я не понимаю, почему это так. Когда атрибут обновления не указан, таблица остается на экране с обновленной активной ячейкой, но ни одна из других ячеек не обновляется (как и ожидалось).

Желаемое поведение может быть достигнуто (неавтоматизированным способом), не указывая атрибут обновления в событии cellAdit AJAX и не щелкая по кнопке Redisplay после редактирования значения ячейки. Как я могу добиться этого автоматическим способом и почему атрибут обновления не работает так, как я ожидаю?

Я использую PrimeFaces 4.0.

4b9b3361

Ответ 1

События rowEdit и cellEdit по дизайну внутри таблицы не обновляют/перерисовывают что-либо еще, кроме текущей строки, даже если явно не указано в атрибуте update. Это следствие того, что PrimeFaces немного переусердствовала, пытаясь свести к минимуму размер ответа. Это имеет смысл в большинстве случаев, но не в вашем конкретном случае. Это стоит отчета о проблеме.

Тем временем, пока они не исправят это поведение, лучше всего использовать <p:remoteCommand> для вызова желаемого метода прослушивания и полного обновления таблицы.

Перезапись

<p:dataTable ...>
    <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
    ...
</p:dataTable>

к

<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
    <p:ajax event="cellEdit" oncomplete="onCellEdit()" />
    ...
</p:dataTable>

Ответ 2

Решение BaLusC не работало напрямую для меня. OnCellEdit нуждается в CellEditEvent в качестве параметра. Мое обходное решение выглядит следующим образом:

<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
    <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
    ...
</p:dataTable>

Ответ 3

Если ни одно из решений не сработало для вас, это сработало для меня

<p:dataTable ... id="theId" widgetVar="theWidget" ...>
                <p:ajax event="rowEdit" listener="#{...}"
                        oncomplete="PF('theWidget').filter()"/> 
....

Я вызываю метод фильтра в виджере PF на ajax complete, любой метод, который выполняет перезагрузку таблицы, должен работать, я использовал фильтр, потому что в моей таблице были фильтры столбцов.

Ответ 4

Я проверил ваш код. Сначала я переместил p: commandButton из p: outputPanel. Вот модифицированный код:

<h:form id="testForm">
            <p:outputPanel id="testContainer">

                <p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">

                    <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />

                    (...)

                </p:dataTable>
            </p:outputPanel>
            <p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
        </h:form>

Я думаю, что этот код работает неправильно. если вы меняете что-либо в таблице, p: ajax каждый раз выводит полную таблицу. Таким образом, программа загружает базовые данные из конструктора TableBean и удаляет новые данные.

basic data

Если я опускаю ваш код p: ajax, на экране не появляются новые данные. Правило refreshButton p: commandButton работает правильно.

При включении update = ": testForm: testContainer" внутри cellEdit Событие AJAX, изменяющее значение ячейки, удаляет данные на экране и только отображает содержимое ячейки (вместе с кнопкой) - я не понять, почему это так.

Я думаю, что это плохой дизайн, добавьте update=":testForm:testContainer" в ajax, потому что он обновляет вашу OutputPanel больше, чем за исключением (первый раз правильно работает, второй раз не может редактировать ячейку, потому что обновление программы до многократной таблицы).

Я не знаю, какова ваша цель. Если вы хотите визуализировать таблицу без commandButton, то можете ли вы указать одно событие javascript или сообщение p: и это исчезнет, ​​вы можете отобразить таблицу.

Я думаю, что если вы опустите обновление в p: ajax или укажите обновление одного p: сообщения и переместите p.commandButton из testContainer, ваш код начнет работать правильно.