我有必要使用延迟加载在数据表中加载一些数据。不幸的是,primefaces dataTable 只支持分页延迟加载,但这对这个项目来说是不可接受的,所以我创建并测试了一些机制来允许使用滚动在数据表中延迟加载(primefaces 的 liveScroll 不是延迟加载)。现在我需要将这些机制移动到一个复合组件中,所以我决定包装 primefaces dataTable:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.prime.com.tr/ui">
<c:interface>
<c:attribute name="var" required="true" targets="tabela"/>
<c:attribute name="value" required="true" targets="tabela" type="java.util.List"/>
<c:attribute name="scrollable" targets="tabela"/>
<c:attribute name="liveScroll" required="false" default="false"/>
<c:attribute name="height" targets="tabela"/>
<c:attribute name="emptyMessage" targets="tabela" default="Nenhuma dado a ser exibido"/>
<c:attribute name="rows" targets="tabela"/>
<c:attribute name="action" method-signature="void method()" required="false"/>
</c:interface>
<c:implementation>
<div id="#{cc.clientId}">
<p:dataTable id="tabela" var="#{cc.attrs.var}" value="#{cc.attrs.value}"
scrollable="#{scrollable}" height="#{cc.attrs.height}"
emptyMessage="#{cc.attrs.emptyMessage}" rows="10">
<c:insertChildren/>
</p:dataTable>
<p:remoteCommand name="comandoAtualizarTabela" action="#{cc.attrs.action}" update="tabela" process="@none"/>
<script type="text/javascript">
if ("#{cc.attrs.liveScroll}") {
var idEscapadoPainelLista = PrimeFaces.escapeClientId("#{cc.clientId}");
jQuery(idEscapadoPainelLista).find(".ui-datatable-scrollable-body").scroll(function () {
if ((this.scrollTop == this.scrollHeight - this.clientHeight))
comandoAtualizarTabela();
});
}
</script>
</div>
</c:implementation>
</ui:component>
当我尝试使用此组件时,导致此异常的行中未显示任何数据:
[#|2012-07-12T09:34:10.010-0300|SEVERE|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=21;_ThreadName=Thread-10;|org.apache.myfaces.view.facelets.el.ContextAwarePropertyNotFoundException: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'bean' resolved to null
at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getType(ContextAwareTagValueExpression.java:79)
at org.primefaces.component.inputtext.InputTextRenderer.getConvertedValue(InputTextRenderer.java:113)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:647)
at javax.faces.component.UIInput.validate(UIInput.java:583)
at javax.faces.component.UIInput.processValidators(UIInput.java:273)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1317)
at javax.faces.component.UIData.process(UIData.java:1919)
at javax.faces.component.UIData.processColumnChildren(UIData.java:1904)
at javax.faces.component.UIData.processValidators(UIData.java:1761)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1317)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1317)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIForm.processValidators(UIForm.java:209)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1324)
at javax.faces.component.UIViewRoot._processValidatorsDefault(UIViewRoot.java:1350)
at javax.faces.component.UIViewRoot.access$500(UIViewRoot.java:74)
at javax.faces.component.UIViewRoot$ProcessValidatorPhaseProcessor.process(UIViewRoot.java:1443)
at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1306)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:793)
at org.apache.myfaces.lifecycle.ProcessValidationsExecutor.execute(ProcessValidationsExecutor.java:38)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at fr.xebia.servlet.filter.ExpiresFilter.doFilter(ExpiresFilter.java:1243)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.gr|#]
[#|2012-07-12T09:34:10.011-0300|SEVERE|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=21;_ThreadName=Thread-10;|izzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'bean' resolved to null
at com.sun.el.parser.AstValue.getTarget(AstValue.java:131)
at com.sun.el.parser.AstValue.getType(AstValue.java:76)
at com.sun.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:195)
at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getType(ContextAwareTagValueExpression.java:75)
... 90 more|#]
添加
该应用程序使用弹簧版本 3.0.7。一旦应用程序有超过 20 个 spring xml 文件,我将只显示一个 spring 文件的一部分......这部分配置我正在使用复合组件测试的对话框:
<bean id="controladorPopupCadastroUnidade" class="com.hrgi.web.cadastro.controladores.popups.ControladorPopupCadastroUnidade" scope="request">
<property name="controladorArmazenamento" ref="controladorArmazenamentoUnidade"/>
<property name="conversorValor" ref="conversorUnidade"/>
<property name="modelo" ref="modeloPopupCadastroUnidade"/>
<property name="popupAlerta" ref="controladorPopupAlerta"/>
<property name="recuperadorValores" ref="unidadeDao"/>
<property name="popupConfirmacao" ref="controladorPopupConfirmacao"/>
</bean>
<bean id="modeloPopupCadastroUnidade" class="com.hrgi.web.ui.modelos.ModeloPopupCRUD" scope="session">
<property name="visivel" value="false"/>
<property name="mensagemSucesso" value="${gerais.lista.sucesso}" />
</bean>
<bean id="controladorArmazenamentoUnidade" class="com.hrgi.persistencia.controladores.ControladorArmazenamento" scope="request">
<property name="armazenador" ref="unidadeDao"/>
<property name="atualizador" ref="unidadeDao"/>
<property name="removedor" ref="unidadeDao"/>
<property name="conversor" ref="conversorUnidade"/>
</bean>
为了帮助您查看问题,这是我尝试使用 cc 的 xhtml 文件的 dataTable 部分:
<h:panelGroup id="painelLista" layout="block" styleClass="clearfix">
<hrgi:dataTable var="bean" value="#{modeloPopupCadastroUnidade.lista}"
scrollable="true" height="145"
action="#{controladorPopupCadastroUnidade.atualizarValores}"
liveScroll="true" rows="10">
<p:column headerText="Nome" style="width: 23%">
<hrgi:cellEditor>
<f:facet name="saida">
<h:outputText value="#{bean.descricao}"/>
</f:facet>
<f:facet name="entrada">
<p:inputText value="#{bean.descricao}" maxlength="35" style="width: 90%"/>
</f:facet>
</hrgi:cellEditor>
</p:column>
<p:column headerText="Sigla">
<hrgi:cellEditor>
<f:facet name="saida">
<h:outputText value="#{bean.sigla}"/>
</f:facet>
<f:facet name="entrada">
<p:inputText value="#{bean.sigla}" maxlength="5"/>
</f:facet>
</hrgi:cellEditor>
</p:column>
<p:column headerText="Fator" sortBy="#{bean.fator}">
<hrgi:cellEditor>
<f:facet name="saida">
<h:outputText value="#{bean.fator}"/>
</f:facet>
<f:facet name="entrada">
<hrgi:spinner value="#{bean.fator}" dinheiro="false" fator="1" local="pt-BR" width="40"/>
</f:facet>
</hrgi:cellEditor>
</p:column>
<p:column headerText="Fracionado" sortBy="#{bean.fracionado}">
<hrgi:cellEditor>
<f:facet name="saida">
<h:outputText value="#{bean.fracionado eq true?'Sim':'Não'}"/>
</f:facet>
<f:facet name="entrada">
<h:selectBooleanCheckbox value="#{bean.fracionado}"/>
</f:facet>
</hrgi:cellEditor>
</p:column>
<p:column headerText="Unitário" sortBy="#{bean.unitario}">
<hrgi:cellEditor>
<f:facet name="saida">
<h:outputText value="#{bean.unitario eq true?'Sim':'Não'}"/>
</f:facet>
<f:facet name="entrada">
<h:selectBooleanCheckbox value="#{bean.unitario}"/>
</f:facet>
</hrgi:cellEditor>
</p:column>
<p:column>
<hrgi:rowEditor action="#{controladorPopupCadastroUnidade.editarValor(bean)}" update="alerta" indice="#{bean.indice}"/>
<p:commandLink title="#{msgGerais['gerais.excluir']}" action="#{controladorPopupCadastroUnidade.removerValor(bean)}" update="painelLista alerta confirmacao" immediate="true">
<h:graphicImage library="img" name="remover.png"/>
</p:commandLink>
</p:column>
</hrgi:dataTable>
</h:panelGroup>
可能问题是 var 属性不能在复合组件之外使用......有没有办法可以在外部公开这个属性?我该如何解决?