2013-05-03 13 views
5

Das unterstützte JSF 2.x Feature der sequentiellen Verarbeitung mehrerer Ajax-Ereignisse funktioniert nicht für mich. Ich habe das folgende Szenario:JSF Ajax Event Queue funktioniert nicht auf Aktionsereignis nach Änderungsereignis

  1. h: input (CHANGE)

    <h:inputText id="consumption_input" 
        value="#{cc.attrs.consumptionInfo.consumption}"> 
        <f:ajax 
        render="#{cc.attrs.outerRenderString}" 
        event="change" listener="#{cc.handleAjaxRequest}" /> 
    </h:inputText> 
    
  2. h: command (ACTION)

    <h:commandButton 
        id="startComparisonButton" 
        action="#{rateComparisonBean.startRateComparison()}" 
        value="#{bundle.rateResultOverview_startComparison}"> 
        <!-- This is to avoid mixed requests, ajax and full requests --> 
         <f:ajax render="@form"/> 
        </h:commandButton> 
    

Die Ereignisse der beiden Elemente sind korrekt gehandhabt, wenn es selbst ausgelöst wird.

Problem tritt auf, wenn beide Ereignisse mit einem Klick ausgelöst werden (Geben Sie einen Wert in textInput ein und klicken Sie anschließend auf die Schaltfläche). Ich erwartete, dass dies zu zwei synchron ausgelösten Ajax-Anfragen führte (CHANGE-TextField und ACTION-commandButton).

Leider gibt es nur eine Ajax-Anfrage (Change-TextField), das zweite Ereignis scheint komplett verloren zu sein.

ich bereits sichergestellt, dass alle Voraussetzungen für ein h: command voll gefüllt sind, wie hier darauf hingewiesen: commandButton/commandLink/ajax action/listener method not invoked or input value not updated

würde ich irgendwelche Hinweise, wie dieses Problem zu lösen bekommen schätzen.

Environment: Glassfish 3, Mojarra 2.1.3-FCS

+0

Interessant ... Haben Sie dies in einer kleinen, leicht replizierten Anwendung verifiziert? Ist es möglich, Mojarra gegen MyFaces auszutauschen und zu sehen, ob Sie das gleiche Verhalten haben? –

+0

Haben Sie jemals * erwartet * Verhalten mit zwei (Aktion) Listener gefeuert? – skuntsel

+0

Haben Sie eine Lösung gefunden? Ich stehe vor dem gleichen Problem. –

Antwort

3

Die JSF Ajax-Aufrufe asynchron sind. Das Senden einer AJAX-Anfrage, in diesem Fall generiert durch <h:inputText> Ereignis, stoppt JavaScipt nicht, um die Ausführung fortzusetzen und in diesem Fall Auslöserschaltknopf auszulösen, was wiederum eine weitere AJAX-Anfrage auslöst. Dennoch sind AJAX-Anfragen tatsächlich auf dem Client in der Warteschlange, um in der genauen Reihenfolge verarbeitet zu werden, in der sie gesendet wurden, was durch JSF 2.0 specification, Kapitel 13.3.2 garantiert wird.

Unten ist mein Testfall:

Aussicht:

<h:form id="form"> 
    <h:inputText id="text" value="#{q16363737Bean.text1}"> 
     <f:ajax render="text2" event="change" listener="#{q16363737Bean.ajaxListenerText}"/> 
    </h:inputText> 
    <h:commandButton id="button" action="#{q16363737Bean.actionButton}" value="Submit"> 
     <f:ajax render="text1 text3" listener="#{q16363737Bean.ajaxListenerButton}"/> 
    </h:commandButton> 
    <br/> 
    <h:outputText id="text1" value="Text 1: #{q16363737Bean.text1}."/> 
    <h:outputText id="text2" value="Text 2: #{q16363737Bean.text2}."/> 
    <h:outputText id="text3" value="Text 3: #{q16363737Bean.text3}."/> 
</h:form> 

Die Bohne:

@ManagedBean 
@ViewScoped 
public class Q16363737Bean implements Serializable { 

    private String text1 = "I'm text 1";//getter + setter 
    private String text2 = "I'm text 2";//getter + setter 
    private String text3 = "I'm text 3";//getter + setter 

    public void ajaxListenerText(AjaxBehaviorEvent abe) { 
     text2 = "I was modified after inputText AJAX call"; 
    } 

    public void ajaxListenerButton(AjaxBehaviorEvent abe) { 
     text1 = "I was modified after AJAX listener call of commandButton"; 
    } 

    public void actionButton() { 
     text3 = "I was modified after commandButton AJAX call"; 
    } 

} 

Nach der Frage für einige Zeit der Prüfung in der Tat heraus, dass ich dachte, dass sehr selten der AJAX-Aufruf der Befehlsschaltfläche wurde verschluckt d Es wurden keine UI-Aktualisierungen vorgenommen. Es scheint so, als ob irgendwo ein Rennen stattfinden sollte. Es ist eine große Frage und es muss weiter untersucht werden.

Also, das ist wahrscheinlich keine Antwort (obwohl ich dachte, es wäre zunächst), aber ein Vorschlag für einen Testfall. Und trotz der Tatsache, dass ich dieses Verhalten sehr selten konfrontiert habe, ist es ein echter Anwendungsfall, und es lohnt sich zu verstehen, was los ist.

0

Zuerst vielen Dank für die schnelle und anspruchsvolle Antwort.

Ein zweiter Test von Grund auf wies darauf hin, dass Ajax-Ereignisse richtig eingereiht sind.

Also noch einmal habe ich das komplexere Szenario oben beschrieben. Die Ursache für das übersprungene Ereignis scheint mit unserem "Überbelegt-Overlay" zusammen zu hängen. Stellen Sie es sich als einen Haufen JavaScript vor, der Formularelemente deaktiviert und während langer Ajax-Anfragen ein Overlay anwendet. Dies geschieht durch einen Rückruf jsf.ajax.addOnEvent.

Wie auch immer, auch wir deaktivieren einige Kontrollen, nach 'Erfolg' ist das Formular in einem ordnungsgemäßen Zustand und das zweite Ereignis könnte behandelt werden.

Momentan gehe ich davon aus, dass die 'temporär' deaktivierte Taste das zugehörige Aktionsereignis kompromittiert, das danach ausgeführt werden sollte.

Wir analysieren derzeit das Problem und ich werde das endgültige Ergebnis so bald wie möglich veröffentlichen.

+0

Haben Sie eine Lösung gefunden? Ich weiß, dass das ziemlich weit zurückgeschrieben wurde, aber ich habe das gleiche Problem. Ich kann keine Lösung finden, ohne das "Belegt-Overlay" zu entfernen oder es zu verzögern. –

Verwandte Themen