Использование p:remoteCommand для обновления p:dataTable

Учитывая следующий код XHTML, который имеет один <p:inputText> и <p:dataTable>, имеющий только два столбца.

<p:remoteCommand name="updateTable" update="dataTable"/>

<p:panel id="panel">
    <p:inputText id="txtValue" value="#{testManagedBean.txtValue}"
                 required="true"/>
    <p:message for="txtValue" showSummary="false"/>
    <p:commandButton actionListener="#{testManagedBean.submitAction}"
                     oncomplete="if(!args.validationFailed) {updateTable();}" 
                     update="panel" value="Submit"/>
</p:panel>

<p:panel id="dataTablePanel" header="Data">
    <p:dataTable id="dataTable" var="row" value="#{testManagedBean}"
                 lazy="true"
                 pageLinks="10"
                 editable="true"
                 rowsPerPageTemplate="5,10,15"
                 rows="10"
                 rowKey="#{row.catId}"
                 editMode="row">

        <p:ajax event="rowEdit" update=":form:panel dataTable"
                listener="#{testManagedBean.onRowEdit}"/>

        <p:column id="id" headerText="Id">
            <h:outputText value="#{row.catId}"/>
        </p:column>

        <p:column id="catName" headerText="Category">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{row.catName}"/>
                </f:facet>
                <f:facet name="input">
                    <p:inputText value="#{row.catName}" label="Category">
                        <f:validateLength minimum="2" maximum="45"/>
                    </p:inputText>
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="Edit" width="100">
            <p:rowEditor/>
        </p:column>
    </p:dataTable>
</p:panel>

При нажатии данного <p:commandButton> вызывается связанный слушатель submitAction() и, наконец, <p:dataTable> обновляется <p:remoteCommand> только в случае успешной проверки.

После этого, если строка, удерживаемая данным <p:dataTable>, обновляется (что, в свою очередь, обновляет <p:panel id="panel"> через <p:ajax> внутри <p:dataTable>. Иногда это необходимо), заданный <p:inputText> в <p:panel id="panel"> вызывает проверку, ее границы становятся красными, подразумевая нарушение связанной проверки, которая должна не происходит.

Если <p:remoteCommand> удалить, а данный <p:commandButton> изменить следующим образом,

<p:commandButton actionListener="#{testManagedBean.submitAction}"
                 update="panel dataTable" value="Submit"/>

удаление oncomplete="if(!args.validationFailed) {updateTable();}"

а атрибут update изменяется с update="panel" на update="panel dataTable", тогда <p:inputText> не вызывает проверки при обновлении строки в <p:dataTable>.

Как запретить <p:inputText> выполнять проверки, когда строка в <p:dataTable> обновляется с использованием <p:ajax>, который, в свою очередь, обновляет <p:panel>, содержащий рассматриваемый <p:inputText>?

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


Связанный управляемый компонент JSF (хотя и совершенно ненужный).

@ManagedBean
@ViewScoped
public final class TestManagedBean extends LazyDataModel<Category> implements Serializable
{
    @EJB
    private final CategoryBeanLocal categoryService = null;
    private String txtValue;  //Getter and setter.
    private static final long serialVersionUID = 1L;

    @Override
    public List<Category> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        setRowCount(categoryService.rowCount().intValue());
        return categoryService.getList(first, pageSize, multiSortMeta, filters);
    }

    public void submitAction() {
        System.out.println("txtValue : " + txtValue);
        txtValue = null;
    }

    public void onRowEdit(RowEditEvent event) {
        System.out.println("onRowEdit() called.");
    }
}

person Tiny    schedule 03.05.2014    source источник


Ответы (1)


После этого, если строка, удерживаемая данным <p:dataTable>, обновляется (что, в свою очередь, обновляет <p:panel id="panel"> через <p:ajax> внутри <p:dataTable>. Иногда это необходимо), данный <p:inputText> в <p:panel id="panel"> вызывает проверку, его границы становятся красными, что означает нарушение связанного проверка, которая не должна происходить.

Это не то, что происходит. Если бы это было правдой, вы бы увидели 3 HTTP-запроса в сетевом мониторе. Но их всего 2 (один из сабмита панели и один из <p:remoteCommand>).

Причина в самом <p:remoteCommand>. Его атрибут process по умолчанию равен @all ("полный вид" ). Вы также можете убедиться в этом, проверив параметр запроса javax.faces.partial.execute в сетевом мониторе. Там написано @all. Другими словами, вся форма также отправляется/обрабатывается, включая эти пустые входные данные.

Вам нужно явно установить его на @this:

<p:remoteCommand name="updateTable" process="@this" update="dataTable"/>
person BalusC    schedule 03.05.2014
comment
Как обычно, не просто ответ, а полное техническое объяснение. Спасибо. - person Omar; 03.05.2014