Frage

Es gibt ein paar Dinge, die ich im Zusammenhang mit der Entwicklung benutzerdefinierter Komponenten in JSF nur schwer verstehen kann.Für die Zwecke dieser Fragen können Sie davon ausgehen, dass alle benutzerdefinierten Steuerelemente Wertbindungen/Ausdrücke (keine Literalbindungen) verwenden, aber ich bin auch an Erklärungen dazu interessiert.

  1. Wo stelle ich den Wert für die Wertbindung ein?Soll das beim Dekodieren passieren?Oder sollte decode etwas anderes tun und dann den Wert in encodeBegin festlegen?
  2. Aus der Wertbindung lesen – Wann lese ich Daten aus der Wertbindung vs.Lesen Sie es aus dem übermittelten Wert und fügen Sie es in die Wertbindung ein?
  3. Wann werden im Zusammenhang mit all dem Aktionslistener auf Formularen aufgerufen?Auf den JSF-Lebenszyklusseiten werden alle Ereignisse erwähnt, die in verschiedenen Schritten auftreten, mir ist jedoch nicht ganz klar, wann nur ein einfacher Listener für eine Befehlsschaltfläche aufgerufen wird

Ich habe einige Kombinationen ausprobiert, bin aber immer auf schwer zu findende Fehler gestoßen, von denen ich glaube, dass sie auf grundlegende Missverständnisse des Ereignislebenszyklus zurückzuführen sind.

War es hilfreich?

Lösung

Es gibt ein ziemlich gutes Diagramm im JSF-Spezifikation Das zeigt den Anforderungslebenszyklus – wichtig für das Verständnis dieser Angelegenheit.

Die Schritte sind:

  • Ansicht wiederherstellen.Der UIComponent-Baum wird neu erstellt.
  • Anforderungswerte anwenden.Bearbeitbare Komponenten sollten EditableValueHolder implementieren.In dieser Phase wird der Komponentenbaum durchlaufen und aufgerufen ProzessDecodes Methoden.Wenn es sich bei der Komponente nicht um etwas Komplexes wie UIData handelt, kann sie nicht viel tun, außer sich selbst aufzurufen dekodieren Methode.Der dekodieren Die Methode macht nicht viel, außer ihren Renderer zu finden und ihn aufzurufen dekodieren Methode, die sich selbst als Argument übergibt.Es ist die Aufgabe des Renderers, jeden übermittelten Wert abzurufen und über ihn festzulegen setSubmittedValue.
  • Prozessvalidierungen.Diese Phase ruft auf ProzessValidatoren was anrufen wird bestätigen.Der bestätigen Die Methode nimmt den übermittelten Wert, konvertiert ihn mit beliebigen Konvertern, validiert ihn mit beliebigen Validatoren und ruft (vorausgesetzt, die Daten bestehen diese Tests) auf setValue.Dadurch wird der Wert als lokale Variable gespeichert.Obwohl diese lokale Variable nicht null ist, wird sie zurückgegeben und nicht der Wert aus der Wertbindung für alle Aufrufe von Wert erhalten.
  • Modellwerte aktualisieren.Diese Phase ruft auf ProzessUpdates.In einer Eingabekomponente wird dies aufgerufen updateModel was wird das bekommen Wertausdruck und rufen Sie es auf, um den Wert für das Modell festzulegen.
  • Anwendung aufrufen.Hier werden Button-Ereignis-Listener usw. aufgerufen (ebenso wie die Navigation, wenn der Speicher ausreicht).
  • Antwort rendern.Der Baum wird über die Renderer gerendert und der Zustand gespeichert.
  • Wenn eine dieser Phasen fehlschlägt (z. B.Wenn ein Wert ungültig ist), springt der Lebenszyklus zu Render Response.
  • Nach den meisten dieser Phasen können verschiedene Ereignisse ausgelöst werden, die gegebenenfalls Listener aufrufen (z. B. Listener für Wertänderungen nach Prozessvalidierungen).

Dies ist eine etwas vereinfachte Version von Ereignissen.Weitere Einzelheiten finden Sie in der Spezifikation.

Ich würde fragen, warum Sie Ihre eigene UIComponent schreiben.Dies ist keine triviale Aufgabe und erfordert ein tiefes Verständnis der JSF-Architektur, um sie richtig zu erledigen.Wenn Sie ein benutzerdefiniertes Steuerelement benötigen, ist es besser, ein konkretes Steuerelement zu erstellen, das eine vorhandene UIComponent (wie HtmlInputText) um einen entsprechenden Renderer erweitert.

Wenn Kontamination kein Problem darstellt, gibt es eine Open-Source-JSF-Implementierung in Form von Apache MyFaces.

Andere Tipps

Aktionslistener, z. B. für a Befehlsschaltfläche, werden während der aufgerufen Anwendung aufrufen Phase, die die letzte Phase vor dem Finale ist Antwort rendern Phase.Dies ist in dargestellt Der JSF-Lebenszyklus – Abbildung 1.

Es ist der einzige Framework, den ich jemals verwendet habe, wenn die Erstellung von Komponenten ein tiefes kompliziertes Prozess wie diesen ist.Keines der anderen Webrahmen (ob in der .NET -Welt oder nicht) macht dies so schmerzhaft, was für mich völlig unerklärlich ist.

Einige der Designentscheidungen hinter JSF ergeben allmählich mehr Sinn, wenn man die Ziele berücksichtigt.JSF wurde für den Tool-Einsatz konzipiert – es stellt zahlreiche Metadaten für IDEs bereit.JSF ist kein Webframework – es ist ein MVP Framework, das als Web-Framework verwendet werden kann.JSF ist in hohem Maße erweiterbar und konfigurierbar – Sie können 90 % der Implementierung pro Anwendung ersetzen.

Die meisten dieser Dinge machen Ihre Arbeit nur komplizierter, wenn Sie lediglich ein zusätzliches HTML-Steuerelement einfügen möchten.

Die Komponente ist eine Zusammensetzung mehrerer InputText- (und anderer) Basiskomponenten, übrigens.

Ich gehe davon aus, dass JSP-includes/tooling-basierte Seitenfragmente Ihren Anforderungen nicht entsprechen.

Ich würde darüber nachdenken, Ihr zu verwenden UIComponentELTag.createComponent um ein zusammengesetztes Steuerelement mit einer UIPanel-Basis zu erstellen und alle seine untergeordneten Elemente aus vorhandenen Implementierungen zu erstellen.(Ich gehe davon aus, dass Sie JSPs/Taglibs verwenden und ein paar andere Vermutungen anstellen.) Sie würden sich wahrscheinlich einen benutzerdefinierten Renderer wünschen, wenn keiner der vorhandenen UIPanel-Renderer die Aufgabe erfüllen würde, aber Renderer sind einfach.

Der beste Artikel, den ich gefunden habe, ist Schreiben von Jsf-Komponenten, was 2 betrifft, wo ich den Wert für eine Wertbindung in Ihrer Komponente lese, haben Sie einen Getter, der so aussieht


public String getBar() {  
     if (null != this.bar) {  
         return this.bar ;  
     }  
     ValueBinding _vb = getValueBinding("bar");  
     return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;  
}
  

Wie kam das in die getValueBinding?In Ihrer Tag-Klasse setProperties-Methode

  if (bar!= null) {  
         if (isValueReference(bar)) {  
             ValueBinding vb = Util.getValueBinding(bar);  
             foo.setValueBinding("bar", vb);  
         } else {  
             throw new IllegalStateException("The value for 'bar' must be a ValueBinding.");  
         }  
     }  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top