Как правильно использовать модальную gwt-bootstrap с gwt-platform?
Я создаю веб-приложение с Google Web Toolkit с использованием GWT-Platform и GWT-Bootstrap. В основном это было почти безупречно, пока я не попытался реализовать всплывающее окно. Представление этих рамок о всплывающих окнах кажется совершенно другим.
GWT-Platform ожидает, что сам всплывающий виджет будет экземпляром com.google.gwt.user.client.ui.PopupPanel
при использовании GWTP RevealRootPopupContentEvent.fire(source, content)
или ведущий addToPopupSlot(child)
метод.
Модал GWT-Bootstrap используется, как и любой другой виджет, который добавляется к базовой панели, но моя цель состоит в том, чтобы у него был отдельный презентатор и представление и, возможно, асинхронно получать его с AsyncProvider.
Я попытался сделать это как PresenterWidget и используя addToSlot(slot, content)
чтобы раскрыть это, но это выглядит не совсем правильно. Не все стили применяются таким образом, и значок закрытия (×), например, не работает.
Я думаю, что я не первый, кто пытается сделать что-то подобное, поэтому, возможно, кто-то нашел правильный способ заставить это работать.
Спасибо!
4 ответа
Вы должны создать вид:
public class MyPopupView extends PopupViewImpl implements MyView {
protected Widget widget;
public interface MyPopupViewUiBinder extends
UiBinder<Widget, MyPopupView> {
}
@UiField(provided = true)
Modal dialogBox;
private MyPresenter presenter;
@Inject
public MyPopupView(final MyPopupViewUiBinder uiBinder,
final EventBus eventBus) {
super(eventBus);
setUpDialog(); // Provides UiField => Before initWidgets
initWidget(uiBinder.createAndBindUi(this));
}
// DialogBox must be overridden to let the presenter handle changes onUnload
private void setUpDialog() {
dialogBox = new Modal() {
@Override
protected void onUnload() {
MyPopupView.this.hide();
}
};
dialogBox.setTitle("Some title");
}
@Override
public void setPresenter(final MyPresenter presenter) {
this.presenter = presenter;
}
@Override
public final void hide() {
dialogBox.hide();
presenter.hide();
}
@Override
public void setAutoHideOnNavigationEventEnabled(final boolean autoHide) {
// TODO Auto-generated method stub
}
@Override
public void setCloseHandler(
final PopupViewCloseHandler popupViewCloseHandler) {
// TODO Auto-generated method stub
}
@Override
public void setPosition(final int left, final int top) {
// TODO Auto-generated method stub
}
@Override
public void show() {
dialogBox.show();
}
@Override
public void center() {
dialogBox.show();
}
@Override
public Widget asWidget() {
return widget;
}
protected final void initWidget(final Widget widget) {
this.widget = widget;
}
}
И файл UIBinder:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:b='urn:import:com.github.gwtbootstrap.client.ui'>
<b:Modal title="Some Title" ui:field="dialogBox">
<!-- Your content -->
</b:Modal>
</ui:UiBinder>
Основываясь на ответе @dominik, я сделал некоторые улучшения, см. Мой Gist. Он содержит некоторые абстрактные базовые классы, которые можно использовать для любой реализации Modal/PopupView. Это немного сложнее, но и чище, потому что мы не проходим весь Presenter
к View
, Интерфейс для View
взаимодействовать с Presenter
когда модал закрыт HasModalUnbind
,
Вы бы использовали эти классы следующим образом. Пример докладчика:
public class ErrorModalPresenter extends ModalPopupPresenter<ErrorModalPresenter.MyView> {
public interface MyView extends ModalPopupView {
DivElement getErrorMessage();
}
private final ErrorEvent error;
@Inject
public ErrorModalPresenter(final EventBus eventBus,
final MyView view,
@Assisted final ErrorEvent error) {
super(eventBus, view);
this.error = error;
}
@Override
public void unbindModal() {
ErrorDismissEvent.fire(this, this);
}
@Override
protected void onBind() {
super.onBind();
//noinspection ThrowableResultOfMethodCallIgnored
getView().getErrorMessage().setInnerText(error.getCause().getMessage());
}
}
Пример вида:
public class ErrorModalView extends ModalPopupViewImpl implements ErrorModalPresenter.MyView {
@UiField(provided = true)
Modal errorModal;
@UiField
DivElement errorMessage;
interface Binder extends UiBinder<Widget, ErrorModalView> {}
@Inject
public ErrorModalView(final EventBus eventBus,
final Binder uiBinder) {
super(eventBus);
errorModal = initModal();
initWidget(uiBinder.createAndBindUi(this));
}
@Override
public DivElement getErrorMessage() {
return errorMessage;
}
}
И UiBinder XML просто для записи:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:b='urn:import:com.github.gwtbootstrap.client.ui'>
<b:Modal ui:field='errorModal' title='Error'>
<g:HTML>
<div ui:field='errorMessage'/>
</g:HTML>
<b:ModalFooter>
<b:Button text='Close' dismiss='MODAL'/>
</b:ModalFooter>
</b:Modal>
</ui:UiBinder>
В unbindModal()
из ErrorModalPresenter
Я запускаю событие, которое ловит родительский ведущий ErrorModalPresenter
, Там модальный ведущий удаляется из контейнера, а затем unbind()
называется на ведущего. Конечно, любое другое решение возможно в unbindModal()
,
Базовые классы предполагают, что модалы - это одноразовые модалы, которые будут удалены после их скрытия. Это поведение может быть изменено в initModal() ModalPopupViewImpl
,
Ваш докладчик всплывающих окон gwtp имеет представление, которое расширяет PopUpViewImpl, который реализует PopupView, и использует множество методов этого интерфейса для отображения всплывающих окон (asPopupPanel(), show(), center() и т. Д.).
Я только начинаю узнавать gwt-bootstrap (выглядит великолепно +caalos0), но кажется, что Modal не реализует PopupView, и поэтому не может быть передан в addToPopupSlot таким образом, как он будет автоматически отображаться gwtp.
Что касается проблемы addToSlot(), используете ли вы RootLayoutPanel или RootPanel? это может быть причиной того, что addToSlot не работает должным образом, так как модальный виджет gwt-bootstrap присоединяется к RootPanel при инициализации, это может вызвать странное поведение макета вместе с приложением, использующим RootLayoutPanel в качестве основы.
Я бы попытался расширить модальный компонент, позволить ему реализовать PopUpView, добавить его в виде поля в PopUpViewImpl, присоединенного к вашему докладчику всплывающих окон, и переопределить функцию PopUpViewImpl asPopupPanel(), чтобы вернуть новый расширенный модальный.
Я полагаю, что вам придется сделать немного кода клея, чтобы он заработал.
Я никогда не использовал всплывающие окна GWT-Platform, поэтому я не знаю точно, как, но я верю, что вам придется создать новый класс, расширяющий PopupPresenter, и сделать все необходимое для того, чтобы он работал.
Кроме того, я думал о GWT-Platform несколько дней назад... и я почти уверен, что когда выйдет первый выпуск GWT-Platform, я создам новый проект для создания этих необходимых клейких кодов.
Если вам нужна помощь с этим, пожалуйста, свяжитесь со мной.
Спасибо, извините за плохую поддержку gwt-платформы.