Как принудительно выполнить фазу сборки на странице JSF 1.2 с помощью JSTL?

Я использую теги JSTL в своем приложении JSF. При определенных действиях мне нужно, чтобы дерево компонентов перестраивалось, как если бы это была начальная сборка. Мои текущие симптомы — неправильный объект для ассоциаций компонентов, повторяющиеся идентификаторы и другие проблемы с устаревшими компонентами. Это использует тег c: foreach (не может использовать повторяющийся тег, см. Пример ссылки), который используется на этапе сборки.

Насколько я понимаю, можно принудительно выполнить перестройку, но я не смог найти, где и как это происходит. Я открыт для решений, которые начинаются на клиенте или на сервере.

Пример кода, который я использую, см. на этой странице динамических вкладок в Richfaces. http://in.relation.to/Bloggers/UsingDynamiclyCreatedRichFacesTabPanelForSearchResults

Примечание. Использование ui:repeat или a4j:repeat невозможно. Подробнее см. на странице примера.

Другое Примечание. Компоненты приложения имеют область действия сеанса, и данные в них должны быть, а не состоянием дерева компонентов.

Обновление Этот вопрос напрямую связан с проблемой, поднятой в этой статьи и первого комментария. Я не знал, как на самом деле сделать обходной путь в первом комментарии, и принятый ответ привел меня к нему.


person Adam    schedule 09.06.2011    source источник


Ответы (1)


Я не думаю, что устаревшие компоненты являются проблемой. Дублирующиеся идентификаторы, в частности, являются побочным эффектом использования тега <c:forEach>. Это связано с тем, что <c:forEach> будет добавлять любые дочерние компоненты в дерево компонентов несколько раз и каждый раз будет пытаться использовать один и тот же идентификатор (в отличие от <ui:repeat>). Это, очевидно, приводит к дублированию идентификаторов (вы заметите, что в примере, на который вы ссылаетесь, они не указали идентификаторы в тегах <c:forEach>).

Я не уверен, что они подразумевают под «фазой сборки просмотра». Если вы посмотрите на документацию по JSF, вы увидите, что там нет такой фазы. В любом случае, когда вы используете <ui:repeat>, пока вызов AJAX, который вы используете для выполнения поиска, повторно отображает rich:tabPanel, тогда он должен работать.

Причина, по которой <ui:repeat> не работает, заключалась в следующем:

Вы не можете использовать повторяющиеся компоненты (ни ui:repeat, ни a4j:repeat) для этого, потому что они работают во время рендеринга страницы и не создают компоненты в дереве JSF, а просто повторяют один и тот же экземпляр.

И в своем примере они использовали:

...
<a4j:commandButton action="#{capitalsBean.search}" value="Search" reRender="output" id="search"/>
...
<a4j:outputPanel id="output">
    <rich:tabPanel id="tapPanel" width="700" rendered="#{not empty capitalsBean.foundCapitals}">
        <c:forEach items="#{capitalsBean.foundCapitals}" var="cap">
        ...

Если вы указываете reRender="output" в поиске a4j:commandButton, почему «время рендеринга страницы» не происходит для tapPanel??

Таким образом, используйте <ui:repeat>, JSTL и JSF, как правило, не очень хорошо ладят друг с другом.

EDIT: я должен был сделать это первым, так как у меня нет опыта работы с rich:tabPanel, но <ui:repeat>, похоже, нельзя использовать с rich:tabPanel (но не по причинам, указанным в примере, на который вы ссылаетесь, поэтому мое замешательство). Однако не используйте <c:forEach>, используйте привязку компонента к rich:tabPanel.

person Gyan aka Gary Buyn    schedule 18.06.2011
comment
Моя проблема не в дублировании идентификаторов из-за того, что тег c: forEach повторяет жестко закодированный идентификатор, так как внутри c: foreach я использую f: subview. Проблема в том, что иногда при изменении страницы дерево компонентов устаревает. Я рассмотрю привязку компонентов, чтобы увидеть, является ли это решением. Я попытаюсь найти правильную фразу для фразы сборки просмотра. - person Adam; 20.06.2011
comment
Я полагаю, что под фазой построения представления я имел в виду новый вид или начальные пути просмотра фазы восстановления, которые затем переходят к фазе ответа рендеринга? - person Adam; 20.06.2011
comment
Честно говоря, я не знаю внутренней работы жизненного цикла JSF до такой степени. Хотя вам это и не нужно. Вызов AJAX запускает жизненный цикл JSF так же, как и любая обычная обратная передача JSF. Единственное отличие состоит в том, что вы можете выбирать, какие компоненты обрабатываются на разных этапах, используя атрибуты process и reRender. Я не понимаю, почему вы получили «устаревшее» дерево компонентов. Единственные вещи, которые могут быть «устаревшими» на стороне клиента, — это те, которые не включены в атрибут reRender. - person Gyan aka Gary Buyn; 21.06.2011
comment
Я еще не вижу, что я удовлетворительно ответил на ваш вопрос... Спасибо, что все равно приняли его. Попробуй привязку и вернись ко мне. - person Gyan aka Gary Buyn; 21.06.2011
comment
Привязка привела меня к правильному решению, подобному этому: tabPanel.getParent().getChildren().clear(); Это очищает панель вкладок от дерева компонентов, и она будет перестроена. - person Adam; 21.06.2011