Как работают PrimeFaces Selectors как в update = "@(. MyClass)"?

Я не понимаю, как Селекторы PrimeFaces (PFS).

<h:outputText value="#{bean.text1}" styleClass="myClass" />
<p:commandButton update="@(.myClass)" />

Я могу использовать его. И я считаю это фантастическим инструментом, хотя он не всегда работает для меня. .myClass - это селектор jQuery на стороне клиента. Как JSF на стороне сервера знает, что обновлять?

Я могу понять, как работают обычные селектора идентификаторов JSF.

<h:outputText value="#{bean.text1}" id="textId" />
<p:commandButton update="textId" />

textId ссылается на идентификатор компонента в дереве компонентов, как определено в файле XHTML на стороне сервера. Поэтому я могу понять, как JSF находит правильный компонент.

Но если вы используете селектора селекторов, используются селектора jQuery на стороне клиента. Как JSF знает, какой компонент должен быть обновлен? Иногда у меня проблемы с PFS. Кажется, он не работает всегда для меня. Есть ли что-то, что вы должны иметь в виду, если используете PFS?

Ответ 1

Вы, наверное, уже знаете, что PrimeFaces использует jQuery под обложками. Серии PrimeFaces основаны на jQuery. Все, что вы указали в @(...), будет использоваться как селектор jQuery в текущем дереве HTML DOM. Для любого найденного HTML-элемента, который имеет идентификатор, именно этот идентификатор в конечном итоге будет использоваться в update.

В принципе, для update="@(.myclass)", PrimeFaces будет под крышкой примерно так:

var $elements = $(".myclass");
var clientIds = [];

$.each($elements, function(index, element) {
    if (element.id) {
        clientIds.push(":" + element.id);
    }
});

var newUpdate = clientIds.join(" "); // This will be used as `update` instead.

Итак, в случае, например,

<h:form id="formId">
    <h:outputText id="output1" styleClass="myclass" ... />
    <h:outputText styleClass="myclass" ... />
    <h:outputText id="output3" styleClass="myclass" ... />
</h:form>

обновление этой командной кнопки

<p:commandButton ... update="@(.myclass)" />

будет иметь тот же эффект, что и

<p:commandButton ... update=":formId:output1 :formId:output3" />

Обратите внимание, что это также работает для автогенерированных идентификаторов. То есть <h:form id> не является обязательным.


Иногда у меня проблемы с PFS. Есть ли что-то, что вы должны иметь в виду, если вы используете PFS?

Может случиться так, что вы выбрали "слишком много" (например, @(form) не выбирает текущую форму, а все формы, точно как $("form") в jQuery!), или что вы фактически ничего не выбрали (когда желаемый HTML Элемент DOM фактически не имеет идентификатора). Изучая идентификаторы элементов в дереве HTML DOM и полезную нагрузку запроса в мониторе трафика HTTP, следует дать подсказки.

Желательные элементы в дереве HTML DOM должны иметь (автогенерированный) идентификатор. Параметр javax.faces.partial.render запроса в мониторе трафика HTTP должен содержать правильные идентификаторы клиентов. Атрибут rendered в дереве компонентов JSF должен оценивать true во время обновления. Etcetera.

В вашем конкретном примере <h:outputText> не будет создан сгенерированный вывод HTML с любым ID. Присвоение ему id должно решить вашу проблему с его обновлением.

Итак, этот пример не будет работать

<h:form>
    <h:outputText value="#{bean.text1}" styleClass="myClass" />
    <p:commandButton value="Update" update="@(.myClass)" /> 
</h:form>

но этот пример будет работать (обратите внимание, что присвоение формы идентификатору необязательно):

<h:form>
    <h:outputText id="myText" value="#{bean.text1}" styleClass="myClass" />
    <p:commandButton value="Update" update="@(.myClass)" /> 
</h:form>