Как правильно использовать FaceletContext.includeFacelet()?

Я использую Mojarra 2.2.8 и Primefaces 5.2. Мне нужно включить разные фаслеты в запрос ajax, поэтому я использую этот код в управляемом компоненте:

FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
if (type.equals("default")) {
        faceletContext.includeFacelet(this, "/defaultDlg.xhtml");
}

В defaultDlg.xhtml у меня есть динамическая вкладка Primefaces:

<p:tabView id="contentTabView" onTabShow="PF('contentDlg').initPosition();" dynamic="true">
    <p:ajax event="tabChange" listener="#{folderView.onTabChange}"/>
    <p:tab title="#{msg['title.documentCard']}">
        <p:panel>

            <!--  some widgets here... -->

        </p:panel>
    </p:tab>
    <p:tab title="#{msg['title.performance']}">
        <!--  DataTable with subTable ... -->
        <p:dataTable  value="#{folderView.performance}" 
                                id="historyTable" widgetVar="historyTable" var="wf">
            <p:columnGroup type="header">
                <p:row>
                    <p:column headerText="#{msg['audit.performance.sendbydesc']}" />
                    <p:column  headerText="#{msg['audit.performance.performerdesc']}" />
                </p:row>
            </p:columnGroup>

            <p:subTable var="task" value="#{wf[5]}">
                <f:facet name="header">
                    <h:outputText value="#{wf[2]}" />
                </f:facet>
                <p:column>
                    <h:outputText value="#{task[2]}" />
                </p:column>
                <p:column>
                    <h:outputText value="#{task[4]}" />
                </p:column>
            </p:subTable>
        </p:dataTable>
    </p:tab>
    <!--  more tabs ... -->

Я просмотрел этот ответ на соответствующий вопрос, где пользователь говорит, что "Использовать FaceletContext - неправильный способ сделать это, потому что позже это вызывает дублирование идентификатора и проблемы с управлением состоянием" без каких-либо объяснений. В моем примере этот метод правильно включает UIComponents из defaultDlg.xhtml для просмотра корня и отображает их на странице.

Но когда я нажимаю на вторую вкладку с подтаблицей или делаю любой запрос ajax, я получаю эту ошибку:

Я думаю, что может возникнуть проблема с сохранением состояния во время ajax-запроса, потому что, если я удалю subTable со второй вкладки, я получаю это предупреждение при каждом ajax-запросе:

Предупреждение: невозможно сохранить динамическое действие с идентификатором клиента 'ntikDoc:j_id69584408_969820d', так как невозможно найти UIComponent Предупреждение: невозможно сохранить динамическое действие с идентификатором clientId 'ntikDoc:j_id69584408_969820d_1', поскольку невозможно найти UIComponent Предупреждение: невозможно сохранить динамическое действие с идентификатором clientId ' ntikDoc:idtFrom:j_id69584408_969829e', потому что UIComponent не может быть найден Предупреждение: невозможно сохранить динамическое действие с идентификатором клиента 'ntikDoc:idtFrom:j_id69584408_96982b4', потому что UIComponent не может быть найден Предупреждение: невозможно сохранить динамическое действие с clientId 'ntikDoc:j_id69584408_96983ee', потому что UIComponent не может быть найден. Предупреждение. Невозможно сохранить динамическое действие с идентификатором clientId 'ntikDoc:idtTo:j_id69584408_9698056', так как не удается найти UIComponent. Не удалось сохранить динамическое действие с clientId 'ntikDoc:idtTo:j_id69584408_969800a ' потому что UIComponent не может быть найден Предупреждение: невозможно сохранить динамическое действие с clientId 'ntikDoc:contentTabView:j_id492561291_69346015', потому что UIComponent не может быть найден found Предупреждение: невозможно сохранить динамическое действие с clientId 'ntikDoc:contentTabView:contentTable:j_id492561291_69346b92', так как не удается найти UIComponent. : невозможно сохранить динамическое действие с идентификатором clientId 'ntikDoc:contentTabView:perTable:j_id492561291_69346cc4', так как не удается найти UIComponent. сохранить динамическое действие с clientId 'ntikDoc:contentTabView:perTable:j_id492561291_69346c10', потому что UIComponent не может быть найден. 'ntikDoc:contentTabView:historyDocTable:j_id492561291_69346ef9', потому что UIComponent не может быть найден

Итак, как правильно использовать faceletContext.includeFacelet?

Инструкции по правильному использованию (в бэк-бине) уже даны в ответе, который вы нашли. Ты это пробовал?

FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
if (type.equals("default")) {
        faceletContext.includeFacelet(this, "/defaultDlg.xhtml");
}
работает правильно только во время сборки представления, но, по-видимому, вы выполнили его после построения представления (например, в методе действия bean-компонента).


person Artem    schedule 15.03.2016    source источник
comment
Я не могу создать компонент ui:include с ViewDeclarationLanguage в реализации mojarra, потому что ui:include не имеет вспомогательного компонента (см. этот java.net/jira/browse/JAVASERVERFACES-3281 ). Так что решение из этого ответа работает только для MyFaces   -  person BalusC    schedule 17.03.2016
comment
Понимаю. Вы рассматривали _1_ вместо этого? Возможно, завернутый в _2_, если он может быть пустым.   -  person Artem    schedule 17.03.2016
comment
да. Я пришел к использованию <ui:include src="#{bean.src}">, завернутого в <c:if test="#{not empty bean.src}">, и это работает. Теперь мне просто любопытно, почему _3_ не работает.   -  person BalusC    schedule 17.03.2016
comment
lu4242 уже ответил на него. Это портит состояние JSF.   -  person Artem    schedule 17.03.2016
comment
Серьезный: java.lang.NumberFormatException: попытка извлечь rowIndex из clientId 'ntikDoc:contentTabView:historyTable:j_id492561291_69346d22:j_id492561291_69346d58' javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) ) в org.primefaces.component.api.UITabPanel.invokeOnComponent(UITabPanel.java:798) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces .component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax. Faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax .faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в javax.faces.component.UIComponent.invokeOnCom ponent(UIComponent.java:1503) в javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:713) в com.sun.faces.application.view.FaceletViewHandlingStrategy.locateComponentByClientId(FaceletViewHandlingStrategy.java:2063) в com.sun .faces.application.view.FaceletViewHandlingStrategy.reapplyDynamicAdd(FaceletViewHandlingStrategy.java:2127) в com.sun.faces.application.view.FaceletViewHandlingStrategy.reapplyDynamicActions(FaceletViewHandlingStrategy.java:2114) в com.sun.faces.application.view. FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:961) на com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99) на com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) на com .sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) в javax.faces.webapp.FacesServlet.service(FacesServlet.java:647) в sun.reflect.GeneratedMethodAccessor167.invoke(неизвестный источник) в sun.reflect .DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke(Method.java:606) в org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:323) в org. .apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:321) в java.security.AccessController.doPrivileged(собственный метод) в javax.security.auth.Subject.doAsPrivileged(Subject.java:536) в org. apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:356) на org.apac he.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:212) в org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1543) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain. java:343) в org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:88) в org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:200) в org.apache.catalina .core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:197) в java.security.AccessController.doPrivileged(собственный метод) в org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:196) в org.primefaces. webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:100) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) в org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationF ilterChain.java:88) в org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:200) в org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:197) в java.security .AccessController.doPrivileged(собственный метод) в org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:196) в org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) в org.apache .каталина.ядро. StandardContextValve.invoke(StandardContextValve.java:175) в org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) в org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) в org. .apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) в org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) в org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter .java:231) в com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) в com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java :195) на com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) на com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) на com.sun.grizzly.http. ProcessorTask.process(ProcessorTask.java:1056) на com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultPro tocolFilter.java:229) в com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) в com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) в com.sun.grizzly.DefaultProtocolChain.execute (DefaultProtocolChain.java:90) на com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) на com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) на com.sun.grizzly. SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) на com.sun.grizzly.ContextTask.run(ContextTask.java:71) на com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) на com .sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) на java.lang.Thread.run(Thread.java:745)   -  person BalusC    schedule 17.03.2016