#jsf-2 #composite-component #uirepeat
#jsf-2 #составной компонент #uirepeat
Вопрос:
Хорошо, я предполагаю, что это может быть ошибкой, но я не совсем уверен. Кто-нибудь может увидеть, что я делаю не так?
Вот ситуация. У меня есть составной компонент, который, кажется, отлично работает, когда он один на странице. Проблема возникает, когда компонент вложен внутри пользовательского интерфейса: repeat. Вот два места, которые я вызываю для компонента (просто для теста):
<q:case aCase="#{userSummaryBackingBean.userCases.get(0)}">
<f:setPropertyActionListener for="clickEvent" target="#{userSummaryBackingBean.value}" value="single"/>
<f:ajax execute="@this" render="@this :westPaneForm"/>
</q:case>
<ui:repeat value="#{userSummaryBackingBean.userCases}" var="aCase">
<li>
<q:case aCase="#{aCase}">
<f:setPropertyActionListener for="clickEvent" target="#{userSummaryBackingBean.value}" value="repeat"/>
<f:ajax execute="@this" render="@this :westPaneForm"/>
</q:case>
</li>
</ui:repeat>
и компонент определяется следующим образом:
<cc:interface>
<cc:attribute name="aCase" type="com.autonomy.calltrack.data.dto.Case"/>
<cc:actionSource name="clickEvent" targets="caseCommandLink"/>
<cc:attribute name="action" targets="caseCommandLink" />
<cc:attribute name="actionSource" targets="caseCommandLink" />
<cc:clientBehavior name="click" event="action" targets="caseCommandLink" default="true"/>
</cc:interface>
<cc:implementation>
<h:commandLink id="caseCommandLink" styleClass="case ui-state-default" title="#{cc.clientId}">
--- more code ---
</h:commandLink>
</cc:implementation>
Как вы можете видеть, вызовы точно такие же, но один элемент работает, а элементы в ui: repeat — нет. Теперь для меня имеет смысл, что все будет проблематично, когда у самого компонента есть ui: repeat . Я имею в виду, как бы вы перенастроили свой ActionSource и т. Д., Не зная идентификатора нужных вам элементов (что внутри повтора в принципе невозможно).
ОДНАКО, когда я помещаю ui: repeat за пределы компонента, я не могу понять, почему все не будет работать. ДЕЙСТВИТЕЛЬНО странно то, что f: ajax, похоже, работает совершенно нормально. ОЧЕНЬ странно.
Я попытался добавить к атрибутам targets префикс: #{cc.ClientID}, и это тоже не помогает (хотя «путь» к компонентам указан правильно). Я делаю что-то не так? У кого-нибудь есть решение?
Хорошо, что-то должно быть не так, потому что даже это не работает:
<ui:repeat value="#{userSummaryBackingBean.userCases}" var="aCase">
<h:commandLink id="caseCommandLink" value="test" styleClass="case ui-state-default">
<f:setPropertyActionListener target="#{userSummaryBackingBean.value}" value="REPEAT"/>
<f:ajax execute="@this" render="@this :westPaneForm"/>
</h:commandLink>
</ui:repeat>
Какого черта я мог пропустить?
Комментарии:
1. Какой JSF impl / version вы используете? Я не могу воспроизвести вашу проблему в Mojarra 2.1.3. Следует отметить, что
<ui:repeat>
это действительно странный зверь, и он был исправлен / значительно улучшен на протяжении всего срока службы Mojarra 2.x. Гораздо лучшим выбором был бы полноценный компонент JSFUIData
, который отображает<ul><li>
как Tomahawk<t:dataList>
, PrimeFaces’<p:dataList>
, RichFaces’<rich:dataList>
и т. Д.2. Я использую 2.0.6, потому что 2.1.3 не поддерживается на Tomcat. Думаю, я мог бы попробовать переключиться на 2.1.3 с Glassfish, у меня просто нет никакого опыта работы с GF. Я также попробую использовать опцию UIData. Спасибо!
3. Хорошо, я попробовал с <p:dataList>, и, похоже, это ничего не изменило. Думаю, я попробую обновить. Если только мне не нужно что-то изменить, чтобы заставить его работать в <p:dataList> . Я оставил раздел <cc:interface> таким же.
4. 2.1.3 определенно поддерживается на Tomcat. Возможно, вы путаете с 2.1.0, который действительно содержал серьезную ошибку в сканере аннотаций (он содержал специфичный для Glassfish код, и он был исправлен как можно скорее для 2.1.1).
5. Действительно? Потому что, когда я просмотрел список известных проблем, в нем говорится, что «неизвестно, работает ли он на Tomcat». Отсюда: javaserverfaces.java.net/nonav/rlnotes/2.1.3/issues.html
Ответ №1:
На моей странице использовались параметры просмотра, но они не были дочерними элементами f:view, поэтому они вызывали проблемы.
Когда я их переместил, все начало работать нормально. Я не уверен, почему, но кажется, что все ломается, когда у вас есть что-то вроде следующего за пределами f:view:
<f:metadata>
<f:viewParam name="caseId" value="#{caseBackingBean.viewingCaseNumber}" />
</f:metadata>
<f:event type="preRenderView" listener="#{caseBackingBean.loadCase}" />
Спасибо за помощь BalusC.
Комментарии:
1.
preRenderView
Вызывается при каждой обратной передаче. Возможно, вы перезагружаете список с другим содержимым или даже очищаете его, из-за чего<ui:repeat>
он больше не получает правильного значения? Если компонент ограничен областью просмотра, вы можете добавитьif (!FacesContext.getCurrentInstance().isPostback()) { /* Original code here */ }
2. Ну, на самом деле метод даже не вызывался. Я поставил точку останова в отладчике, и она никогда не срабатывала, пока компонент находился в повторе. Хотя за пределами повтора все работало нормально…
3. Ну что ж. Вы приняли во внимание, что
<f:metadata>
это не работает в файлах мастер-шаблонов? (тот, на который вы ссылаетесь<ui:composition template>
). Он должен быть включен в шаблон представления верхнего уровня. Смотрите также Документацию по тегу: download.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs /…4. Хммм. Интересно, было ли это фактором. Мне нужно будет протестировать и посмотреть, что я смогу найти. Возможно, я неправильно использовал этот тег.
5. Хорошо, это вообще не было ошибкой. Похоже, у меня были метаданные не в том месте, И мой <f:event> был дочерним элементом <f:metadata> . Как только я переместил вещи (согласно вашей ссылке), они начали работать. Единственная проблема заключается в том, что когда я нажимаю на ссылку, а затем возвращаюсь на страницу, я не могу щелкнуть другую ссылку. Это не проблема, когда страница является областью сеанса. Это происходит только с областью представления. Ну что ж, я продолжу работать над этим.