JSTL, составной, NamingContainer и prependId - PullRequest
1 голос
/ 23 августа 2011

Я написал составной компонент и хочу использовать зарезервированный EL #{component.clientId} для привязки JQuery.Чтобы использовать этот извлеченный clientId в другом месте на странице (вне компонента), я использую JSTL, чтобы сохранить его в переменной области представления.Странно то, что JSTL препятствует естественному поведению составного компонента, добавляя свой идентификатор перед дочерними элементами (поведение NamingContainer).Я знаю, что JSTL немного сложнее, мешая другим компонентам (например, ui:repeat) из-за вещей жизненного цикла, но здесь я не понимаю этого поведения.

Некоторый конкретный код лучше, чем эта длинная речь:

<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:rich="http://richfaces.org/rich"
        xmlns:c="http://java.sun.com/jsp/jstl/core"    
        xmlns:composite="http://java.sun.com/jsf/composite">
    <composite:interface>
        […]
    </composite:interface>
    <composite:implementation>
        <rich:dataTable id="mySoLovedDataTable" […]>
            #{component.clientId}
            <!-- Commenting or uncommenting this line make the whole point -->
            <c:set var="targetClientId" value="#{component.clientId}" scope="view" />
            […]
        </rich:dataTable>
    </composite:implementation>
</html>

С закомментированной строкой #{component.clientId} дает что-то вроде j_idt261:mySoLovedDataTable.

С закомментированной строкой это дает только mySoLovedDataTable.

1 Ответ

3 голосов
/ 23 августа 2011

JSTL работает во время сборки представления.Он выполняется в тот момент, когда JSF анализирует шаблон представления в полноценное и воспроизводимое дерево компонентов JSF.JSF работает во время просмотра.Он выполняется в тот момент, когда JSF кодирует дерево компонентов в связку HTML.Вы можете визуализировать это следующим образом: JSTL сначала работает сверху вниз и выдает результат только с тегами JSF.Затем, во время фазы ответа рендеринга JSF, JSF будет работать сверху вниз и производить HTML-результат.

Другими словами, JSTL и JSF не работают синхронно, как вы ожидаете от кодирования.Обычно вы хотели бы использовать Facelets '<ui:param> вместо JSTL <c:set>.

<ui:param name="targetClientId" value="#{component.clientId}" />

Обратите внимание, что это на самом деле ничего не устанавливает в любой области видимости.Это просто создает своего рода «псевдоним» для данного выражения.Я не уверен, работает ли он в вашем конкретном случае так, как вы намереваетесь, но, насколько я понимаю, функциональное требование, вы хотели бы иметь возможность получить идентификатор клиента <rich:dataTable> далее, после компонента.В этом случае лучше использовать binding:

<rich:dataTable binding="#{table}" ...>
    ...
</rich:dataTable>

<script>
    var $table = jQuery("[id='#{table.clientId}']");
    // ...
</script>
...