Составной компонент внутри пользовательского интерфейса: повторяется, приводит к тому, что ActionSource не запускается

#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. Гораздо лучшим выбором был бы полноценный компонент JSF UIData , который отображает <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> . Как только я переместил вещи (согласно вашей ссылке), они начали работать. Единственная проблема заключается в том, что когда я нажимаю на ссылку, а затем возвращаюсь на страницу, я не могу щелкнуть другую ссылку. Это не проблема, когда страница является областью сеанса. Это происходит только с областью представления. Ну что ж, я продолжу работать над этим.