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

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

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

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

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

[ERROR] Невозможно объявить id = "lastName" и ui: field = "lastNameField" в том же элементе Элемент (: 23)

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

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

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

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

Ответ 1

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

Ответ 2

Вы можете упростить ответ Томаса (немного), обратившись к идентификатору в 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>

Ответ 3

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