2009-03-17 8 views
5

Ich habe eine Tag-Klasse, die UIComponent und UIOutput erweitert. In dieser Klasse habe ich encodeBegin und encodeEnd, womit ich meinen contextWriter verwenden kann, um ein beliebiges HTML-Tag auszugeben, das ich auch verwenden möchte, indem ich writer.startElement ("div", myComponent) und so weiter verwende.Wie kann ich vorhandene JSF-Komponenten zu meinen eigenen benutzerdefinierten Komponenten hinzufügen?

Mein Problem ist jetzt, dass ich zum Beispiel eine anstelle der Verwendung des writer.startElement einfügen muss. Ich kann dies tun, indem ich getChildren(). Add (HtmlCommandButton button = new HtmlCommandButton()); aber wenn ich es so mache, kann ich die Komponente nicht ausgeben, wo ich sie erscheinen lassen möchte, so wie ich es mit write.startElement kann.

Hat jemand gute Lösungen, wie ich Richfaces-Tags, JSF-Tags und ähnliches in meiner eigenen Taglibrary nutzen kann? Kurz gesagt, was ich wirklich tun möchte, ist in meiner encodeBegin:

writer.startElement("a4j:commandButton", myComponent); 
writer.writeAttribite("action", "#{Handler.myAction}", null); 
writer.endElement("a4j:commandButton"); 

Dank durch Voraus

Antwort

3

Sie können den ResponseWriter nicht verwenden, wie Sie möchten. Zwei Möglichkeiten, wie Sie unterordnete Steuerelemente programmgesteuert hinzufügen können, sind entweder über das bindende Attribut (see this answer) oder an der Stelle, wo Steuerelemente normalerweise erstellt werden (in JSPs, das heißt in tag class).

Es gibt zwei Möglichkeiten für JSF-Komponenten, andere Steuerelemente zu enthalten: als untergeordnete Elemente oder als benannte Facetten. Komponenten steuern immer, wie sie ihre Facetten rendern. Wenn sie ihre Kinder darstellen sollen, müssen sie für getRendersChildren als wahr zurückgeben.

Dieser ungetesteten Code ist, aber die Sequenz geht in etwa so:

@Override 
    public boolean getRendersChildren() { 
    return true; 
    } 

    @Override 
    public void encodeBegin(FacesContext context) 
     throws IOException { 
    // should really delegate to a renderer, but this is only demo code 
    ResponseWriter writer = context.getResponseWriter(); 
    writer.startElement("span", this); 
    String styleClass = getStyleClass(); 
    writer 
     .writeAttribute("class", styleClass, "styleClass"); 

    UIComponent headerComponent = getFacet("header"); 
    if (headerComponent != null) { 
     headerComponent.encodeAll(context); 
    } 

    writer.startElement("hr", null); 
    } 

    @Override 
    public void encodeChildren(FacesContext context) 
     throws IOException { 
    ResponseWriter writer = context.getResponseWriter(); 
    for (UIComponent kid : getChildren()) { 
     kid.encodeAll(context); 
     writer.startElement("br", null); 
    } 
    } 

    @Override 
    public void encodeEnd(FacesContext context) 
     throws IOException { 
    ResponseWriter writer = context.getResponseWriter(); 
    writer.endElement("span"); 
    } 
+0

Ausgezeichneter Mann. Ich muss das gerade testen. Die myComponent.encodeAll (Kontext) war genau das, wonach ich suchte. Vielen Dank! –

1

nicht wirklich eine Antwort, eher eine Vermutung, aber vielleicht könnten Sie eine der facelets Kontrollen verlängern?

Alternativ können Sie auch direkt Facelets verwenden - was genau das ist, was Sie wirklich wollen, obwohl ich es nicht selbst benutzt habe. Oder Sie könnten UIOutput-Steuerelemente hinzufügen, an denen HTML angezeigt werden soll, und den jeweiligen Wert für den gewünschten HTML-Code festlegen - genau das tut f: verbatim unter der Haube, so scheint es beim Betrachten des Quellcodes:)

+0

Ja Im bereits UIOutput erstreckt. Ich bin nicht sicher, was ich erweitern würde, was mir die Möglichkeit gibt, andere Komponenten auszugeben, anstatt nur Tags auszugeben. Danke für die Antwort. –

+0

Ich habe mich an einigen Kontrollen umgesehen und die Frage bearbeitet. Ich habe nichts getan, was du selbst mit Google und den Faces und Facelets nicht machen könntest. –

+0

Ausgezeichnet. Ich werde das so schnell wie möglich versuchen (wahrscheinlich innerhalb von 48 Stunden, da ich diese zwei Tage nicht arbeite). Vielen Dank für Ihre Zeit –

Verwandte Themen