GWT - Как определить виджет вне иерархии макета в XML-файле uibinder - PullRequest
5 голосов
/ 18 марта 2010

это мой первый пост. Я надеюсь, что кто-то может мне помочь.
Я ищу способ определить виджет в XML-файле макета UiBinder отдельно, не будучи частью иерархии макета. Вот небольшой пример:

<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">

<g:Label ui:field="testlabel" text="Hallo" />
<g:HTMLPanel>       
...
</g:HTMLPanel>

Компиляция не удалась, поскольку элемент ui: UiBinder ожидает только один дочерний элемент.
В Java Code я получу доступ и свяжу виджет Label как обычно:

@UiField Label testlabel;

Например, это может быть полезно при определении Grid или FlexTable - я хочу определить метки для заголовка таблицы в файле макета XML, а не программно в коде.

Большое спасибо заранее

Ответы [ 3 ]

2 голосов
/ 19 марта 2010

Извините, я не могу, UiBinder просто не поддерживает такой синтаксис. Подумайте об этом - куда пойдет этот виджет? Должен ли он быть добавлен в дерево DOM? Компилятору также трудно определить, следует ли удалить этот код как неиспользуемый.

Вам придется подождать, пока команда GWT создаст пользовательские теги для Grid (как они это сделали, например, с DockLayoutPanel). Я не ожидал бы, что такая функциональность для FlexTable, хотя она подразумевается под дизайном для динамического контента, то есть все равно добавляется программно.

0 голосов
/ 02 мая 2010

Я не уверен, что у вас есть такая же необычная мотивация, чтобы разместить более двух корневых виджетов под тегом uibinder. Во всяком случае, так я это делаю.

Поскольку тег uibinder допускает использование только одного корневого виджета, я помещаю HTML-тег ui в качестве корневого виджета, а затем складываю несколько псевдо-корневых виджетов в этот тег.

В следующем примере обратите внимание, что у фактического корневого виджета нет имени поля ui:, потому что мы не собираемся его использовать. Насколько нам известно, эффективными корневыми виджетами являются "tabLayout" и "content".

Файл Hello.ui.xml:

<ui:UiBinder
  xmlns:ui="urn:ui:com.google.gwt.uibinder"
  xmlns:g="urn:import:com.google.gwt.user.client.ui">
  <g:HTML>
    <g:TabLayoutPanel ui:field="tabLayout"  ... >
      blah ... blah
    </g:TabLayoutPanel>
    <g:VerticalPanel ui:field="content">
      blah .. blah
    </g:VerticalPanel>
  </g:HTML>
</ui:UiBinder>

Не расширяйте составные элементы как Java-код за шаблоном. Создайте класс, импортированный точкой входа вашего модуля, или используйте шаблон непосредственно в вашем модуле.

У меня есть разные причины, по которым мне нужно более одного корневого виджета. В этом примере я прикрепляю «эффективный корневой виджет» условно:

public class Hello
  implements EntryPoint{

  private static HelloUiBinder uiBinder = GWT.create(HelloUiBinder.class);

  interface HelloUiBinder
    extends UiBinder<Widget, Hello>{}

  @UiField TabLayoutPanel tabLayout;
  @UiField VerticalPanel content;

  @Override public void onModuleLoad() {
    uiBinder.createAndBindUi(this);

    if (condition1)
      RootPanel.get().add(tabLayout);
    else
      RootPanel.get().add(content);

    blah ... blah 
  }
}

Итак, хитрость заключается в том, чтобы вообще не использовать настоящий корневой виджет.

0 голосов
/ 19 марта 2010

Понимание UiBinder Dev Guide - ключ к пониманию того, как правильно структурировать шаблоны UiBinder.

Итак, если все, что вы хотите сделать, это создать виджет и не иметь его изначально в DOM, то вообще не упоминайте его в шаблоне UiBinder. Вместо этого в файле Java, который идет с вашим шаблоном UiBinder, создайте его и добавьте в панель, определенную в вашем шаблоне.

Например, поместите это в свой шаблон:

<g:HTMLPanel ui:field='container'>       
...

И поместите это в свой файл Java:

@UiField HTMLPanel container;
public MyWidget() {
  initWidget(uiBinder.createAndBindUi(this));
  Label testLabel = new Label("hallo");
  // Do whatever you want to testLabel
  container.add(testLabel);
}
...