Вступление
Вероятно, все вы знаете главу в документации GWT о декларативном расположении с помощью UiBinder . В нем описан способ привязки отдельных компонентов панели к ее представлению пользовательского интерфейса, написанному на языке разметки, похожем на HTML. Это позволяет вам определить макет пользовательского интерфейса и скомпилировать его, так что вам не нужно делать это непосредственно в коде панели и иметь возможность переключать пользовательский интерфейс в любое время с другим.
Но что, если вам нужно переключить макет, когда приложение уже запущено?
В этот момент приходит связыватель Dynamic UI . Он позволяет указывать информацию о привязке в панели HTML и GWT так же, как в UiBinder GWT. Разница лишь в том, что вам не нужно иметь шаблон макета в это время. Вы можете загрузить его позже с помощью службы или динамически прочитать его / изменить его в коде.
Итак, давайте посмотрим, как вы это сделаете.
витрина
Для тех, кто нетерпелив: вы можете найти демонстрацию этого в проекте acris-showcase-widgets .
Предположим, мы собираемся создать простой калькулятор того, сколько кораблей имеет наш космический флот. Надо «вождям» отвечать за свои корабли. Таким образом, у нас будет два текстовых поля для ввода числа и кнопка для расчета всего:
<div class="dyn-panel"> <div ui:field="message" class="dyn-message">Status messages are shown here</div> <div class="fleet-container"> <div ui:field="description" class="dyn-description"></div> <input type="text" ui:field="ashtarShips" /> <input type="text" ui:field="ptahShips" /> <button ui:field="recalculateFleet">Recalculate fleet</button> </div> </div>
Как вы можете видеть, мы будем выводить сообщения о состоянии / ошибках и иметь ссылку, указывающую на описание (вы можете удивиться, почему это тег «div», объяснение будет следовать).
Хорошо, давайте построим панель. Начнем с определения связующего:
public class DynamicallyBoundPanel extends Composite { interface DynamicallyBoundPanelUiBinder extends DynamicUiBinder<Widget, DynamicallyBoundPanel> {} private static final DynamicallyBoundPanelUiBinder binder = GWT.create(DynamicallyBoundPanelUiBinder.class); ... }
Как видите, синтаксис аналогичен синтаксису GWT, вместо UiBinder мы используем DynamicUiBinder .
И поля будут следовать:
@UiField protected Label message; // this is acris-widget Hyperlink because GWT's misses wrap method! @UiField protected Hyperlink description; @UiField protected TextBox ashtarShips; @UiField protected TextBox ptahShips; @UiField protected Button recalculateFleet;
Хм, теперь единственное, чего не хватает, это клей между шаблоном и переплетом:
public DynamicallyBoundPanel() { // load the template e.g. from service ... String htmlTemplate = "<div class=\"dyn-panel\"><div ui:field=\"message\" class=\"dyn-message\">Status messages are shown here</div><div class=\"fleet-container\"><div ui:field=\"description\" class=\"dyn-description\"></div><input type=\"text\" ui:field=\"ashtarShips\" /><input type=\"text\" ui:field=\"ptahShips\" /><button ui:field=\"recalculateFleet\">Recalculate fleet</button</div></div>"; binder.setViewTemplate(htmlTemplate); // known from GWT UiBinder - initialize initWidget(binder.createAndBindUi(this)); ... }
В целях пояснения шаблон HTML непосредственно помещается в переменную «htmlTemplate». Обычно вы будете читать его из сервиса.
Каждый тег, который должен быть сопоставлен с виджетом поля на панели, должен иметь соответствующее имя в атрибуте ui: field . Значение совпадает с именем поля.
Основное отличие между GWT UiBinder и DynamicUiBinder заключается в настройке шаблона. Прежде чем выполнить binder.createAndBindUi (this) , связыватель должен иметь его. Вы можете рассматривать связыватель как фабрику панелей, поэтому последовательные вызовы пары методов setViewTemplate / createAndBindUi могут привести к разным результатам (если шаблон изменяется). Таким образом, вы можете сохранить одну такую фабрику связывателя инициализированной и предоставить только шаблон, основанный на требованиях логики бизнеса.
С помощью связанных полей вы можете выполнить обычное кодирование GWT, например, установив значение сообщения:
message.setText("You accessed " + event.getValue() + ". Thank you for your interest in AcrIS. For more information, please visit http://acris.googlecode.com");
И это все для витрины … не стесняйтесь проверить это на страницах AcrIS .