Вызовы API p: datatable selectAllRows не вызывают событие rowSelect

У меня есть p:dataTable с selectionMode=multiple, который связывает события rowSelect и rowUnselect:

<p:dataTable 
    widgetVar="myDatatable" 
    selectionMode="multiple" 
    selection="#{myBean.selection}">
    <p:ajax event="rowSelect" listener="#{myBean.onSelect}" />
    <p:ajax event="rowUnselect" listener="#{myBean.onUnselect}" />
... (columns)
</p:dataTable>

Выбор строк работает нормально, myBean.selection обновляется и myBean.onSelect() вызывается.

Теперь я хотел добавить кнопки для (отмены) выбора всех элементов на панели инструментов. Я создал два <p:commandLink>s:

<p:commandLink onclick="PF('myDatatable').selectAllRows();" 
            update="actionbarForm">select all</p:commandLink>
<p:commandLink onclick="PF('myDatatable').unselectAllRows();" 
            update="actionbarForm">unselect all</p:commandLink>

Выбор, кажется, работает, я вижу, что либо все элементы (не) выбраны. Однако ни myBean.selection, ни myBean.onSelect() не обновляются/не вызываются. Что мне нужно сделать, чтобы включить это?


person Bob    schedule 02.12.2016    source источник
comment
Я понятия не имею, но что, так что я должен заняться отладкой, чтобы узнать больше, но из любопытства, что вы отлаживали? Аякс звонит? Сетевой трафик? Проверен исходный код PrimeFaces (файлы js и java). Много вещей, которые вы можете сделать   -  person Kukeltje    schedule 02.12.2016
comment
Я проверил, при вызове selectAllRows() нет ни Ajax-Call, ни сетевого трафика. Я также пытался вызвать PF('myDatatable').fireRowSelectEvent() до или после вызова selectAllRows(), но не смог определить правильные параметры.   -  person Bob    schedule 02.12.2016
comment
И если вы используете его с «командной кнопкой», например. запускает вызов со страницы (после использования функции selectAllRows). Например. как в витрине «Несколько с клавишами Meta и Shift»   -  person Kukeltje    schedule 02.12.2016
comment
Добавление действия в commandLink ничего не меняет. Пример Multiple с клавишами Meta и Shift показывает только результат выбора, который у меня работает при выборе элементов по одному.   -  person Bob    schedule 02.12.2016
comment
Я попробовал это последнее В витрине, запустив PF('widget_form_multipleDT').selectAllRows() из консоли разработчика, а затем нажав кнопку «Просмотр». Затем кажется, что сервер имеет все строки и отображает их. Просто нет события rowSelect   -  person Kukeltje    schedule 02.12.2016
comment
Спасибо за подсказку. Если я пропущу <p:ajax>-события, выбор будет правильно обновлен для моей таблицы данных. Но мне нужны события, так что опускать их, к сожалению, нельзя...   -  person Bob    schedule 02.12.2016
comment
Я думаю, что у меня есть решение после изучения исходного кода (он очень читаем). Я опубликую его здесь, если вы после этого отправите запрос на улучшение с PF, чтобы события «toggleSelect» запускались для этих двух вызовов javascript.   -  person Kukeltje    schedule 02.12.2016


Ответы (1)


Эти два вызова javascript API PrimeFaces никоим образом не взаимодействуют ни с одним из событий ajax. Это можно увидеть в datatable.js в selectAllRows() и unselectAllRows() Если вы не используете ajax, а используете обычную "отправить" с помощью кнопки, вы увидите, что PrimeFaces расширяет выбор до "все" на стороне сервера. Для этого он передает @all значение выбора на сервер.

Вы также увидите в исходном коде, что уже есть некоторый код для отправки 'toggleSelect` ajax, поэтому я поместил его в функцию, расширяющую таблицу данных PrimeFaces:

PrimeFaces.widget.DataTable.prototype.fireToggleSelectEvent = function(checked) {
    //fire toggleSelect event
    if(this.cfg.behaviors) {
        var toggleSelectBehavior = this.cfg.behaviors['toggleSelect'];

        if(toggleSelectBehavior) {
            var ext = {
                    params: [{name: this.id + '_checked', value: checked}
                ]
            };

            toggleSelectBehavior.call(this, ext);
        }
    }
}

После вызова (un)selectAllRows() через виджет вы также можете вызвать эту функцию со значением true (выбрать) или false (отменить выбор) в качестве параметра.

Если вы затем добавите toggleSelect ajax в свой datatable

<p:ajax event="toggleSelect" listener="#{dtSelectionView.onToggleSelect}" update=":form:msgs" />

и в вашем bean-компоненте добавьте обработчик:

public void onToggleSelect(ToggleSelectEvent event) {
    FacesMessage msg = new FacesMessage(event.isSelected() ? "All Selected" : "All Unselected");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

Все работает. (PrimeFaces 6.0, код протестирован на витрине)

Вы также можете переопределить как (un)selectAllRows в файле данных PrimeFaces datatable.js, так и в конце вызвать fireToggleSelectEvent, чтобы все было в одном функциональном вызове (или объединить оба отдельных вызова в одну пользовательскую функцию).

person Kukeltje    schedule 02.12.2016