2010-06-19 16 views
10

¿Es posible reemplazar elemento html conocido con mi componente widget? (Énfasis en la palabra 'reemplazar', no quiero poner el widget en ese elemento. :)¿Cómo reemplazar el elemento con mi widget GWT?

<body> 
    <img /> 
    <div /> 
    <a id="tmpEl" /> 
    ... 
    <img /> 
</body> 

se convertiría en

<body> 
    <img /> 
    <div /> 
    <div class="gwt-panel">...</div> 
    ... 
    <img /> 
</body> 

Probé algo como esto ...

tmpEl.getParentElement().replaceChild(myPanel.getElement(), tmpEl); 

... pero los elementos DOM resultantes fueron 'sordos', es decir, no recibieron eventos de clic. (Para realizar este trabajo que probablemente tendría que llamar RootPanel.get(). Adoptan (Widget), pero ese método no es accesible.)

Por un segundo pensé HTMLPanel.addAndReplaceElement podría ser la respuesta, pero eso solo funciona cuando su elemento 'marcador de posición' es hijo (directo) del widget HTMLPanel. Lo cual obviamente no es mi caso. . :(

Nota por favor que sólo sabe Identificación de ese elemento, no estoy creando En pocas palabras: Necesito exactamente lo que dice la pregunta

En cuanto a la 'manipulación DOM en el nivel más alto'. : con mucho gusto manipular el DOM al más alto nivel posible si se me permite colocar widget de cambio de ese elemento marcador de posición

Respuesta

-1

yo sugeriría intentar algo como esto ...

<body> 
    <a id="tmpEl" /> 
</body> 

entonces en crear alguna parte. un widget (p. Reproductor textBox)

TextBox tb = new TextBox(); 

Después de haber creado el widget se puede obtener es objeto DOM utilizando tb.getElement() (no estoy seguro de que es el nombre del método correcto, pero definitivamente es algo así como getElement)

Después de que se puede utilizar

Element parent = Document.getElementById('tmpEl').getParent(); 
parent.removeChild(Document.getElementById('tmpEl')); 
parent.appendChild(tb.getElement()); 

Una cosa más que añadir() hace es llamar Widget.onAttach() en el widget que se agrega al panel. onAttach hace algún trabajo para registrar el widget para recibir eventos.

Puede intentar llamar a tb.onAttach(); También podría ser necesario llamar a RootPanel.detachOnWindowClose (tb); (como se menciona en una publicación anterior)

+0

Eso es, básicamente, la solución que he mencionado en la pregunta original, y no funciona. Solo que en lugar de replaceChild usaste removeChild + appendChild. También con appendChild pone el elemento al final de su elemento principal, que no es necesariamente donde podría haber estado el marcador de posición. –

+0

Debo decir que tengo la sensación de que estás haciendo algo mal aquí: no se parece al estilo gwt, al menos no para mí. – markovuksanovic

+0

¿Ha adjuntado el widget a un widget principal? De esta forma, el widget no se adjuntará automáticamente. – markovuksanovic

0

Estoy de acuerdo con markovuksanovic - debe considerar la manipulación DOM en un "nivel superior". Por ejemplo, la funcionalidad que necesita se proporciona a través de la interfaz InsertPanel, que FlowPanel implementos:

FlowPanel mainPanel = new FlowPanel(); 
Hyperlink link = new Hyperlink("Something cool"); 
mainPanel.add(link); 
mainPanel.add(new Label("Bla bla")); 

// Now we want to replace the first element of the FlowPanel with a TextBox 
// We can do that by its index... 
mainPanel.remove(0); 

// ...or Widget instance 
mainPanel.remove(link); 

// Now we add a TextBox at the beginning 
mainPanel.add(new TextBox(), 0); 

Como se puede ver, este código es mucho más fácil de leer (al menos para mí), no manipular el DOM directamente (haciendo referencia a través de ids y tal).Por supuesto, hay lugares donde la manipulación DOM directa es beneficiosa (optimizando, sobre todo), pero en su mayor parte, evitaría hacer malabares con Elementos, IDs y cosas similares :) (al menos en GWT)

+0

No necesito crear un enlace, gracias. Necesito reemplace el existente. Lea la pregunta. –

+0

Acabo de presentar un caso de uso: la forma en que desea manipular el DOM es común en los marcos JS "normales", pero GWT intenta crear una capa entre el árbol DOM subyacente y lo que usted Quiero agregarle. Entonces, siguiendo el comentario de markovuksanovic, mostré cómo lo que describiste en tu pregunta, podría hacerse de la "manera GWT".Por supuesto, manipular el DOM directamente es a menudo una necesidad, cuando se trabaja con aplicaciones existentes o cuando se intenta integrar un widget/aplicación de GWT con un sitio web existente. –

+0

Y ese es exactamente el caso aquí: estoy escribiendo un widget para otro sitio web que no tiene GWT. Tengo some text en el lugar donde el propietario del sitio web quiere que se cree mi widget. Al renderizar el widget, necesito una URL para leer más contenido del atributo ("href" entra en juego), y si algo sale mal, el elemento delimitador sirve como una forma alternativa de servir el contenido: un buen enlace cliqueable. Colocar el widget en el elemento de anclaje es un no-no por varias razones obvias. –

5

Parece que llamando al widget.onAttach() después de insertar el widget en DOM hace el truco.

class MyWidget extends Composite 
{ 
    ... 

    public void attach() 
    { 
    /* Widget.onAttach() is protected 
    */ 
    onAttach(); 

    /* mandatory for all widgets without parent widget 
    */ 
    RootPanel.detachOnWindowClose(this); 
    } 
} 

tmpEl.getParentElement().replaceChild(myWidget.getElement(), tmpEl); 
myWidget.attach(); 

El crédito va a André al Google Web Toolkit group.

aunque todavía me pregunto por qué no hay RootPanel.addAndReplaceElement (Widget, Element), similar a HTMLPanel.addAndReplaceElement(Widget, Element).

+0

Debería funcionar, Anchor.wrap() hace básicamente lo mismo. –

+0

Trabajos. :) Y sí, es lo mismo (como se menciona en la publicación de grupo), ¡salud! –

3

La solución probablemente no sea tan diferente de lo que sugirió Igor. Escribiría algo como esto:

RootPanel rootPanel = RootPanel.get(); 
Element anchorElement = DOM.getElementById("tmpEl"); 
Anchor anchor = Anchor.wrap(anchorElement); 

rootPanel.remove(anchor); 
rootPanel.insert(new HTML("<div class='gwt-panel'>...</div>", 0); 
+0

Creo que es fundamentalmente diferente, porque esto probablemente funcionaría. Envolver el elemento existente con el widget fue donde André M. de GWT-group se inspiró con su solución. –

0

Estoy haciendo algo muy similar. Estoy leyendo el contenido de <div>; usando los elementos encontrados en el <div> para construir un menú animado que luego reemplaza el contenido original. El menú animado es un widget.

Parece que funciona ...

// DisclosurePanel is a widget 
DisclosurePanel accordion_panel = processAccordion(accordionElement); 
// accordionElement is found in the DOM (it's a com.google.gwt.user.client.Element) 
// clear what was there 
accordionElement.setInnerText(""); 
// add the widget in 
RootPanel.get(accordionElement.getId()).add(accordion_panel); 
+1

Eso es porque no está REEMPLAZANDO el elemento, está insertando su widget en él. –

Cuestiones relacionadas