Когда и как генерируется clientID в JSF?
Чтобы лучше понять генерацию clientID в JSF (2.x), может кто-нибудь объяснить мне, когда точно JSF генерирует ID клиента (какая фаза жизненного цикла, время сборки или время рендеринга...)?
И как будет сгенерирован идентификатор клиента (если вы предоставляете / не предоставляете идентификатор компонента, а не случайно, с использованием определенной логики...)?
1 ответ
Чтобы лучше понять генерацию clientID в JSF (2.x), может кто-нибудь объяснить мне, когда точно JSF генерирует ID клиента (какая фаза жизненного цикла, время сборки или время рендеринга...)?
Это должно закончиться в ответе HTML. Таким образом, он генерируется во время ответа рендера. Если вы установите точку отладки UIComponent#getClientId()
метод, то вы увидите дальше в стеке, что (в случае Мохарра) RenderResponsePhase#execute()
был вызван. Это достаточный намек на текущую фазу жизненного цикла при достижении точки останова.
И как будет сгенерирован идентификатор клиента (если вы предоставляете / не предоставляете идентификатор компонента, а не случайно, с использованием определенной логики...)?
Конкретная реализация реферата UIComponent#getClientId()
метод можно найти в UIComponentBase#getClientId()
, Его исходный код можно найти на grepcode. Как это будет сгенерировано, просто описано в его javadoc:
public abstract String getClientId(FacesContext context)
Возвратите идентификатор стороны клиента для этого компонента, генерируя его при необходимости. Связанный
Renderer
если таковые имеются, будет предложено преобразовать clientId в форму, подходящую для передачи клиенту.Возврат из этого метода должен быть одинаковым в течение всего времени существования экземпляра, если только
id
свойство компонента изменено, или компонент помещен вNamingContainer
чей идентификатор клиента изменяется (например,UIData
). Однако даже в этих случаях последовательные вызовы этого метода всегда должны возвращать одно и то же значение. Реализация должна выполнить следующие шаги при определении clientId:Найдите ближайшего предка этого компонента в иерархии представлений, которая реализует
NamingContainer
, ВызовgetContainerClientId()
на нем и сохранить результат какparentId
локальная переменная. ВызовgetId()
на этом компоненте и сохранить результат какmyId
локальная переменная. ЕслиmyId
являетсяnull
, вызовcontext.getViewRoot().createUniqueId()
и присвоить результатmyId
, ЕслиparentId
не являетсяnull
, позволятьmyId
равныйparentId +
UINamingContainer.getSeparatorChar(javax.faces.context.FacesContext)
+ myId
, ВызовRenderer.convertClientId(javax.faces.context.FacesContext, java.lang.String)
, проходяmyId
и вернуть результат.
Довольно ясно, не так ли? Наиболее важной частью, возможно, является запоминание компонентов, которые реализуют NamingContainer
и, таким образом, добавить их идентификатор клиента. В стандарте JSF 2.x это как минимум <h:form>
, <h:dataTable>
, <ui:repeat>
, <f:subview>
а также <cc:implementation>
, Если вы аккуратно дадите всем компонентам фиксированный идентификатор, то вы также увидите этот шаблон в сгенерированном HTML-выводе.
Если вы не дадите этим компонентам фиксированный идентификатор, то вместо этого будет использоваться сгенерированный JSF идентификатор, который можно получить с помощью UIViewRoot#createUniqueId()
(как уже намекнуло в приведенном выше выдержке Javadoc). Его Javadoc говорит:
public String createUniqueId()
Генерация идентификатора для компонента. Идентификатор будет иметь префикс
UNIQUE_ID_PREFIX
и будет уникальным в дочерних поддеревьях не-NamingContainer этогоUIViewRoot
,
Этот префикс j_id
, Неясно, как реализация должна генерировать ее, поэтому все разработчики могут ее реализовать. Обычно они используют увеличенный индекс количества компонентов в дереве. Итак, первый компонент, UIViewRoot
, может получить удостоверение личности j_id1
, Его первый ребенок мог получить удостоверение личности j_id2
, Etcetera. Вы можете отследить логику, поставив точку останова отладки на UIViewRoot#createUniqueId()
метод или даже UIComponentBase#setId()
метод.
Смотрите также:
- Как узнать идентификатор клиента компонента для обновления / рендеринга ajax? Не удается найти компонент с выражением "foo", на которое ссылается "bar"
- По умолчанию JSF генерирует непригодные идентификаторы, которые несовместимы с CSS-частью веб-стандартов.
- Избегайте дублирования идентификаторов при повторном использовании композиций Facelets в том же контейнере именования