2011-06-23 11 views
19

Bazı Ajax davranışlarını kullanan bir JSF 2 bileşik bileşenim var. Kompozit bileşenimin içinde <f:ajax> etiketine listener yöntemini eklemek istiyorum, ancak listener yöntemi, <composite:interface>'da <composite:attribute> olarak sağlanmalıdır.JSF 2 - Bileşik bileşen arabirimine Ajax dinleyici yöntemini nasıl ekleyebilirim?

benim kompozit bileşenlerin içinde <f:ajax> etiketi şu anda böyle bir dinleyiciye kodlanmış olan

:

fasulye dinleyici yöntem bu imzası vardır
<f:ajax 
    event="valueChange" 
    execute="@this" 
    listener="#{controller.genericAjaxEventLogger}" 
    render="#{cc.attrs.ajaxRenderTargets}" /> 

:

public void genericAjaxEventLogger(AjaxBehaviorEvent event) 
     throws AbortProcessingException { 
    // implementation code... 
} 

Ben kompozit istiyorum Bileşen böyle bir şey olması için sayfa kendi olay yöntemini sağlayabilir, ancak arayüz için doğru sözdizimini çözemiyorum.

<f:ajax 
    event="valueChange" 
    execute="@this" 
    listener="#{cc.attrs.ajaxEventListener}" 
    render="#{cc.attrs.ajaxRenderTargets}" /> 

Bunu nasıl yapabilirim?

ÇÖZÜM İLE GÜNCELLEME:

Ben BalusC önerdiği yaklaşım aldı ve o inşaat büyük. İlgili snippet'leridir:

<composite:interface> 
    <composite:attribute 
     name="myattributeUpdatedEventListener" 
     method-signature="void listener()" 
     required="true" /> 
    ... 
</composite:interface> 

Ajax etiketi benim kompozit bileşeni

<f:ajax 
    event="valueChange" 
    execute="@this" 
    listener="#{cc.attrs.myattributeUpdatedEventListener}" 
    render="#{cc.attrs.ajaxRenderTargets}" /> 

Ben kompozit bileşeni kullanmak benim sayfa yer kullanılan kompozit bileşende arabirim bildirimi

<h:form> 
    <compcomp:myCompositeComponent 
     myattributeUpdatedEventListener="#{myBackingBean.updatedEventListenerXYZ}" /> 
</h:form> 

Ve destek kabuğumdaki yöntem

public void updatedEventListenerXYZ() { 
    // do something here... 
} 
+0

Çözüm için teşekkürler, gerçekten bana yardımcı oluyor. –

+0

Bir parametreyi bir yöntemden geçirerek yapmak mümkün mü? Örnekte # {myBackingBean.updatedEventListenerXYZ} örneğini geçirmek yerine, # {myBackingBean.myMethod (cc.attrs.myparam)} gibi bir şey iletmek yerine, – dcalap

cevap

21

Eğer AjaxBehaviorEvent argüman kurtulmak ise, argüman günlüğü için (zorunlu ise

public void genericAjaxEventLogger() { 
    // ... 
} 

o zaman

<cc:attribute name="ajaxEventListener" method-signature="void listener()" /> 

kullanabilir?

SEVERE: javax.faces.FacesException: wrong number of arguments 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    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:326) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013) 
    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.grizzly.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(Unknown Source) 
Caused by: java.lang.IllegalArgumentException: wrong number of arguments 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234) 
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297) 
    at com.sun.faces.facelets.el.ContextualCompositeMethodExpression.invoke(ContextualCompositeMethodExpression.java:177) 
    at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:450) 
    at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447) 
    at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:113) 
    at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:102) 
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:300) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
    ... 28 more 
:

<cc:attribute name="ajaxEventListener" method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)" /> 

Ancak şöyle + Mojarra 2.1.1 GF 3.1 üzerinde

<f:ajax listener="#{cc.attrs.ajaxEventListener}" /> 

ile beklendiği gibi), o zaman bu burada çalışmıyor, niteliğini yeniden belirlemeniz gerekir

Bunun bir hata olup olmadığından emin değilim. Bunun için biraz daha zamana yatırım yapmalıyım. Ancak, MethodExpression'u özniteliklerden alan ve doğru sayıda argümanla çağrıştıran bir destek bileşeni oluşturarak çözümlenebilir oldu.

); ben destek bileşeni zaten aklında oldu fonksiyonel şartı ulaşmak için yeni yollar açık kapılar koyar inanıyoruz olursa olsun

<ui:component 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:cc="http://java.sun.com/jsf/composite" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
> 
    <cc:interface componentType="testCC"> 
     <cc:attribute name="ajaxEventListener" method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)" /> 
    </cc:interface> 
    <cc:implementation> 
     <h:commandButton value="Submit"> 
      <f:ajax listener="#{cc.ajaxEventListener}" /> 
     </h:commandButton> 
    </cc:implementation> 
</ui:component> 

package com.example; 

import javax.el.MethodExpression; 
import javax.faces.component.FacesComponent; 
import javax.faces.component.UINamingContainer; 
import javax.faces.context.FacesContext; 
import javax.faces.event.AjaxBehaviorEvent; 

@FacesComponent(value="testCC") 
public class TestCC extends UINamingContainer { 

    public void ajaxEventListener(AjaxBehaviorEvent event) { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     MethodExpression ajaxEventListener = (MethodExpression) getAttributes().get("ajaxEventListener"); 
     ajaxEventListener.invoke(context.getELContext(), new Object[] { event }); 
    } 

} 

ile: Burada tam bir başlama örneği

+1

Bunun için teşekkürler. CC arabiriminde bir eylem yöntemi bildiren çok sayıda örnek buldum, ancak hiçbiri bir dinleyici yöntemini bildirmek için kullanmıyor. 'Dinleyici()' 'method-signature' parçası, JSF tarafından anlaşılan özel bir değer midir? –

+4

Yöntem adı alakalı değil. Hatta xyz() 'adında da kullanabilirsiniz. Bu sadece kendini tanımlayan bir örnekti. En önemlisi, yöntem dönüşü ve parametre türlerinin tam nitelikli sınıf adıdır. – BalusC

+0

Tam olarak aradığım şey;) – boblemar

1

Arabirimin, bir öznitelik ayarlamak için nasıl kullanılacağına ve uygulama içinde referans alınmasına ilişkin bir örnek. Çağırılacak yöntemin yöntem imzasını tanımlamanız gerekir. Bu, bileşik bileşen işleyicisini, # {cc.attrs.ajaxEventListener} ifadesinde bulunan bir değer ifadesinden ziyade bir yöntem değeri olduğunu bildirir.

<cc:interface name="composite-comp" 
    <cc:attribute required="true" name="ajaxEventListener" 
        method-signature="void f1(javax.faces.event.AjaxBehaviorEvent)" /> 
    <cc:attribute required="true" name="ajaxRenderTargets" /> 
</cc:interface> 

<cc:implementation> 
    . 
    . 
    . 
    <f:ajax event="valueChange" execute="@this" 
     listener="#{cc.attrs.ajaxEventListener}" 
     render="#{cc.attrs.ajaxRenderTargets}" /> 
</cc:implementation> 
+0

neyi test ettiniz/kullandınız? Bu Mojarra 2.1.1 ile GF 3.1 ve Tomcat 7 için benim için başarısız. – BalusC