Как заменить элемент моим виджетом GWT? - PullRequest
11 голосов
/ 19 июня 2010

Можно ли заменить известный элемент HTML моим компонентом виджета?(Акцент на слове «заменить», я не хочу помещать виджет в этого элемента.:)

<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 (). Accept (widget) , но этот метод недоступен.)

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

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

Какдля «манипулирования DOM на более высоком уровне»: я буду рад манипулировать DOM на максимально возможном уровне, если он позволит мне разместить виджет вместо этого элемента-заполнителя.

Ответы [ 5 ]

5 голосов
/ 20 июня 2010

Кажется, что вызов 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 .

Мне все еще интересно, почему нет RootPanel.addAndReplaceElement (Widget, Element) , аналогично HTMLPanel.addAndReplaceElement (Widget, Element) .

3 голосов
/ 20 июня 2010

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

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 голосов
/ 06 июня 2011

Я делаю нечто очень похожее. Я читаю содержимое <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);
0 голосов
/ 19 июня 2010

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

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 выгодна (оптимизация, прежде всего), но по большей части я бы избегал жонглирования Elements, ID и т. Д.

0 голосов
/ 19 июня 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...