2010-06-19 2 views
10

Возможно ли заменить известный элемент html с моим компонентом виджета? (Акцент на слове «заменить», я не хочу, чтобы поместить виджет в этот элемент. :)Как заменить элемент на мой виджет GWT?

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

станет

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

Я пытался что-то вроде этого ...

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

... но результирующие элементы DOM были «глухими», то есть они не получали события щелчка. (Для того, чтобы сделать эту работу, я бы, наверное, назвать RootPanel.get(). Принять (виджет), но этот метод не доступен.)

На секунду я подумал HTMLPanel.addAndReplaceElement может быть ответ, но это работает только тогда, когда ваш элемент «placeholder» является (прямым) дочерним элементом виджета HTMLPanel. Это, очевидно, не мое дело. . :(

Примечание пожалуйста, что я знаю только идентификатор этого элемента, я не создаю его Проще говоря: мне нужно именно то, что говорит вопрос

Что касается "манипулирования DOM на более высоком уровне. Я счастливо манипулировать DOM на максимально высоком уровне, если это позволяет мне поместить виджет вместо этого шаблонного элемента

ответ

-1

Я хотел бы предложить вам попробовать что-то вроде этого ...

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

затем где-нибудь создать. виджет (например, TextBox виджет)

TextBox tb = new TextBox(); 

После создания виджета вы можете получить его объект DOM с помощью tb.getElement() (я не уверен, что это правильное название метода, но это определенно что-то вроде getElement)

После того, что вы могли бы использовать более

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

Одна вещь, что добавление() делает это вызов Widget.onAttach() на виджет, который добавляется к панели. onAttach выполняет некоторую работу, чтобы зарегистрировать виджет для получения событий.

Вы можете попробовать позвонить tb.onAttach(); Также может потребоваться вызвать RootPanel.detachOnWindowClose (tb); (как упоминалось в предыдущем посте)

+0

Это в основном решение я уже упоминал в оригинальный вопрос, и он не работает. Только это вместо replaceChild вы использовали removeChild + appendChild. Кроме того, с помощью appendChild вы помещаете элемент в самый конец своего родителя, что необязательно там, где мог бы быть местозаполнитель. –

+0

Я должен сказать, что у меня такое чувство, что вы делаете что-то неправильно здесь - это не похоже на стиль gwt, по крайней мере, на меня. – markovuksanovic

+0

Вы подключили виджет к родительскому виджету? Таким образом, виджет не будет автоматически подключен. – markovuksanovic

0

Я согласен с markovuksanovic - вы должны рассмотреть DOM-манипуляцию на «более высоком уровне». Например, функции, которые вам нужно обеспечивается через интерфейс InsertPanelFlowPanel, который реализует:

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); 

Как вы можете видеть, этот код является гораздо более удобным для чтения (по крайней мере для меня), вы не манипулировать DOM напрямую (ссылка через идентификаторы и т. д.).Конечно, есть места, где выгодна прямая манипуляция DOM (оптимизация, в первую очередь), но по большей части я бы избегал манипулирования элементами, идентификаторами и т. Д. :) (по крайней мере, в GWT)

+0

Мне не нужно создавать ссылку, спасибо. замените существующий. Пожалуйста, прочитайте вопрос. –

+0

Я просто представлял вариант использования - способ, которым вы хотите манипулировать DOM, является обычным явлением в «нормальных» JS-инфраструктурах, но GWT пытается создать слой между базовым деревом DOM и тем, что вы хочу добавить к нему. Итак, после комментария марковуксановича, я показал, как то, что вы описали в своем вопросе, может быть сделано «способом GWT».Разумеется, манипулирование DOM напрямую является необходимостью при работе с существующими приложениями или попытке интегрировать виджет/приложение GWT с существующим веб-сайтом. –

+0

И это именно так: я пишу виджет для другого сайта GWT-unaware. У меня есть some text, где владелец сайта хочет, чтобы мой виджет был создан. При рендеринге виджета мне нужен URL-адрес для чтения дополнительного контента (вступает в игру атрибут «href»), и если что-то пойдет не так, элемент привязки служит альтернативным способом обслуживания контента - хорошей старой ссылкой на клики. Размещение виджета в элементе привязки не имеет значения по нескольким очевидным причинам. –

5

Кажется, что вызов widget.onAttach() после вставки виджета в DOM делает трюк.

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(); 

Кредит отправляется Андре в Google Web Toolkit group.

Я до сих пор удивляюсь, хотя почему нет RootPanel.addAndReplaceElement (Widget, Element), подобно HTMLPanel.addAndReplaceElement(Widget, Element).

+0

Должен работать, Anchor.wrap() делает в основном то же самое. –

+0

Работы. :) И да, это то же самое (как упоминалось в групповом посте), ура! –

3

Решение, вероятно, не так сильно отличается от того, что предложил Игорь. Я бы написал что-то вроде этого:

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

Я считаю, что это принципиально другое, потому что это, вероятно, сработает. Обертка существующего элемента с виджетами заключалась в том, что Андре М. из группы GWT вдохновил его решение. –

0

Я делаю что-то очень похожее. Я читаю содержимое <div>; используя элементы, найденные в <div>, для создания анимированного меню, которое затем заменяет исходное содержимое. Анимированное меню - виджет.

Это похоже на работу ...

// 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

Это потому, что вы не ЗАМЕНА элемента, вы вставляете свой виджет в него. –

Смежные вопросы