3 Stimmen

Teilen von Komponenten zwischen Ansichten - wie kann ich mein Design verbessern?

Ich arbeite an einer JSF-Webanwendung, deren Zweck darin besteht, ein Befehlszeilenprogramm zu umfassen. Eine ihrer Hauptfunktionen ist die Möglichkeit, eine Sitzung zwischen Benutzern zu teilen (z. B. für Kurse), sodass, wenn eine Eingabe an eine Instanz der Anwendung gesendet wird, die Ausgabe an jeden Abonnenten für diese Sitzung gesendet wird.

Als Ergebnis dieses Designs besteht die Webanwendung hauptsächlich aus einem view-scoped Bean, das einen Controller der Befehlszeilenanwendung anfordern wird. Es wurde auch gewählt, eine Sitzung mit dem URL-Fragment zu identifizieren (z. B. meine Domain / meine App / #SESSIONID), sodass jeder, der die URL mit dem gleichen Fragment verwendet, Eingaben und Ausgaben teilt, wobei er seine eigene Instanz des view-scoped-Beans verwendet, aber den gleichen Controller teilt

Um Ergebnisse an alle Abonnenten zu senden, verwende ich Primefaces Push. Die Ergebnisse sind in erster Linie Text, der an das Terminal der Webanwendung angehängt werden muss, aber einige Befehle führen zur programmatischen Erstellung eines JSF-Komponenten. Um dies zu handhaben, rendere ich diese Komponenten einfach zu einem String, den ich an alle Abonnenten sende.

Dann habe ich festgestellt, dass der zugehörige UIComponent hinzugefügt werden muss, um Ajax-Anfragen von Komponenten (und von jedem Abonnenten) zu verarbeiten, muss zur UIViewRoot hinzugefügt werden im Kontext von (weiß nicht, wie man das ausdrücken soll) jedem view-scoped-Bean.

Tatsächlich habe ich zuerst versucht, einen "gemeinsamen Container" (ein UIForm) an eine Eigenschaft des view-scoped-Beans zu binden, in dem ich die programmatisch erstellten Komponenten platzieren würde, aber ich musste offensichtlich das Huhn-und-Ei-Problem bewältigen, über das @BalusC in seinem Blog spricht, weil die Komponente bei jeder Ajax-Anfrage erneut hinzugefügt wurde. Das Setzen von javax.faces.PARTIAL_STATE_SAVING auf false hat auch nicht geholfen (ich verwende MyFaces 2.2.5)

Also, als eine Art Workaround, wenn der Controller eine neue Komponente erstellen muss, fügt er im Wesentlichen die ID der Komponente den übertragenen Daten hinzu (in einem zu Json konvertierten HashMap), und alle Abonnenten werden (zurück) ein remoteCommand an ihre eigene Instanz des view-scoped-Beans auslösen, um den "gemeinsamen Container" von ihrer eigenen UIViewRoot aus zu aktualisieren.

Das funktioniert, aber mir gefällt diese Art und Weise nicht!

Also:

  1. Wäre es möglich, diese Art von Sharing zwischen view-scope Beans (mit dem gleichen Namen), die in unterschiedlichen HTTP-Sitzungen gespeichert sind, zu handhaben? Ich beziehe mich auf diese Antwort von @BalusC... vielleicht durch Spielen mit javax.faces.ViewState - wäre das überhaupt möglich?

  2. Gibt es einen "magischen" Scope für mein derzeit view-scoped Bean, den ich verwenden könnte?

  3. Sollte ich eher ein vollkommen anderes Design verwenden?

Danke!

0voto

Igor Punkte 91

Wenn Sie Daten zwischen allen Benutzern Ihrer Anwendung teilen möchten, können Sie den Anwendungsbereich verwenden.

Wenn Sie den Ansichtsbereich weiterhin verwenden möchten, können Sie Ihren Ansichtsbereich mit einem anderen Anwendungsbereich verbinden, wie folgt:

ApplicationView appView = BeanUtil.findBean("applicationView", FacesContext.getCurrentInstance());

import javax.faces.context.FacesContext;

public class BeanUtil {

@SuppressWarnings("unchecked")
public static  T findBean(String beanName, FacesContext context) {
    return (T) context.getApplication().evaluateExpressionGet(context,
            "#{" + beanName + "}", Object.class);
}

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X