Добавить идентификатор в поле с объявлением поля 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 виджетов.