JSTL, составной, NamingContainer и prependId
Я написал составной компонент и хочу использовать зарезервированный 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 ответ
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>