2009-03-17 35 views
5

Tengo una clase de etiqueta que extiende UIComponent y UIOutput. En esta clase tengo encodeBegin y encodeEnd, y puedo usar mi contextWriter para generar cualquier tipo de etiqueta html que quiera usando writer.startElement ("div", myComponent), etc.¿Cómo agregar componentes JSF existentes a mis propios componentes personalizados?

Mi problema ahora es que tengo que insertar, por ejemplo, a en lugar de utilizar writer.startElement. Puedo hacer esto haciendo getChildren(). Add (HtmlCommandButton button = new HtmlCommandButton()); pero al hacerlo así, no puedo mostrar el componente donde quiero que aparezcan, como puedo con write.startElement.

¿Alguien tiene alguna buena solución sobre cómo puedo aprovechar las etiquetas richfaces, las etiquetas JSF y similares en mi propia taglibrary? En pocas palabras lo que yo realmente quiero hacer es dentro de mi encodeBegin:

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

Gracias por adelantado

Respuesta

3

No puede usar el ResponseWriter como lo desee. Dos formas en que puedo pensar cómo agregar controles secundarios mediante programación son a través del atributo vinculante (see this answer) o en el lugar donde generalmente se crean los controles (en JSPs, es decir, tag class).

Hay dos formas en que los componentes JSF pueden contener otros controles: como elementos secundarios o facetas con nombre. Los componentes siempre controlan cómo rinden sus facetas; si van a representar a sus hijos, deben devolver verdadero para getRendersChildren.

Este es el código no probado, pero la secuencia es algo como esto:

@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

Excelente hombre. Solo tengo que probar esto. MyComponent.encodeAll (context) era exactamente lo que estaba buscando. ¡Muchas gracias! –

1
No

realmente una respuesta, más de una suposición, pero tal vez usted podría extender uno de los controles facelets?

Como alternativa, use facelets directamente, que parece ser exactamente lo que quiere aunque no lo haya usado yo mismo. O puede agregar controles UIOutput donde quiera que aparezca HTML y establecer el valor de cada uno para el HTML que desea que aparezca; esto es exactamente lo que hace f: textbatim bajo el capó, o eso parece al mirar el código fuente:)

+0

Sí ya estoy extendiendo UIOutput. No estoy seguro de qué ampliaría, lo que me da la capacidad de generar otros componentes en lugar de solo generar etiquetas. Gracias por responder. –

+0

He observado algunos controles y he editado la pregunta. ¡No he hecho nada que no pudieras hacer tú mismo con Google y las fuentes de Faces y Face realmente! –

+0

Excelente. Probaré esto lo antes posible (probablemente dentro de las 48 horas ya que no estoy en el trabajo estos dos días). Muchas gracias por su tiempo –

Cuestiones relacionadas