Добавить идентификатор в поле с объявлением ui:field

Я пытаюсь объявить эти элементы в моем XML UiBinder:

<label for="lastName">Last Name:</label>
<input type="text" id="lastName" ui:field="lastNameField" maxlength="150" />

Проще говоря, метка, связанная с вводом текста.

Однако, когда я пытаюсь скомпилировать, я получаю эту ошибку:

[ОШИБКА] Невозможно объявить id="lastName" и ui:field="lastNameField" в одном и том же элементе Element (:23)

Это кажется идиотским ограничением, тем более что ui:field не генерирует идентификатор. Единственное решение, которое я нашел до сих пор, - это назначить идентификатор в самом коде Java следующим образом:

@UiElement InputElement lastNameField;
...
lastNameField.setId("lastName");

Это добавляет ненужный беспорядок в мою Java. Это также добавляет сложности, что если этот идентификатор будет обновлен где-то в будущем, объявление <label> в XML также необходимо будет обновить (и для метки нет @UiElement, поэтому он практически полностью невидим со стороны Java).

Есть ли способ добавить идентификатор к элементу с объявлением ui:field из самого XML UiBinder?


person Roddy of the Frozen Peas    schedule 17.04.2013    source источник


Ответы (3)


UiBinder использует идентификатор для реализации своей магии ui:field, поэтому нет, вы не можете установить его из XML.

Способ сделать это - иметь константу Java с идентификатором и использовать ее с обеих сторон:

@UiField(provided = true)
final String lastNameId = Document.get().createUniqueId();

@UiField InputElement lastNameField;

…

lastNameField.setId(LAST_NAME_ID);

и в XML:

<ui:with field="lastNameId" type="java.lang.String"/>

…

<label for="{lastNameId}">Last Name:</label>
<input ui:field="lastNameField" maxlength="150"/>

Обратите внимание, что я не тестировал приведенный выше код с type="java.lang.String", вместо этого я всегда использовал класс, содержащий различные идентификаторы (точнее, интерфейс с генератором)

Альтернативы:

  • если можете, используйте альтернативный синтаксис для <label>:

    <label>Last Name: <input ui:field="lastNameField" maxlength="150"/></label>
    
  • прочитайте значение for="" из Java, чтобы использовать его в setId(), таким образом, по крайней мере, вы удалите дублирование, но у вас все еще будет проблема, что ваши идентификаторы, возможно, не будут уникальными (как только вы используете свой виджет UiBinder более одного раза )

    <label ui:field="lastNameLabel" for="lastName">Last Name:</label>
    <input ui:field="lastNameField" maxlength="150" />
    
    @UiField LabelElement lastNameLabel;
    @UiField InputElement lastNameField;
    
    …
    
    lastNameField.setIf(lastNameLabel.getHtmlFor());
    
person Thomas Broyer    schedule 17.04.2013
comment
А как насчет debugId? stackoverflow.com/questions/11845544/ - person Jonathan; 18.04.2013
comment
Идентификаторы отладки предназначены для… отладки. Злоупотребление инструментами редко приносит пользу в долгосрочной перспективе. - person Thomas Broyer; 19.04.2013

Вы можете упростить ответ Томаса (немного), обратившись к идентификатору в uibinder следующим образом:

<b:ControlLabel for="{testTextBox.getId}">TextBox</b:ControlLabel>
<b:TextBox ui:field="testTextBox"></b:TextBox>

// In code behind:
@UiField(provided = true)
TextBox testTextBox = new TextBox();
...
testTextBox.setId("test");
this.initWidget(uiBinder.createAndBindUi(this));

Если вы используете GWT Bootstrap, есть удобная функция, позволяющая подключать все только в xml:

<b:ControlLabel for="{testTextBox.getId}">TextBox</b:ControlLabel>
<b:TextBox ui:field="testTextBox" b:id="test"></b:TextBox>
person Rob    schedule 25.11.2013
comment
Большое спасибо за раздел про gwt-bootstrap, мне он был крайне полезен! - person annouk; 25.01.2014

b:id="test" работает для всех виджетов gwtbootstrap3.

person Greg Sheremeta    schedule 06.02.2015
comment
К сожалению, вопрос касается ванильного GWT, а не какого-то варианта начальной загрузки. - person Roddy of the Frozen Peas; 06.02.2015
comment
Это полезная информация. Bootstrap очень популярен. - person Greg Sheremeta; 07.02.2015
comment
gwtbootstrap и gwtbootstrap3 — это две разные библиотеки. В этом случае они имеют одинаковую функциональность, но это не всегда так. Мой пост о gwtbootstrap3, а он упомянул gwtbootstrap. - person Greg Sheremeta; 08.02.2015