Замена маркера во вложенной структуре UiBinder / обработка ошибок с помощью MVP

#gwt #mvp #uibinder

#gwt #mvp #uibinder

Вопрос:

Я использую DockLayoutPanel в качестве своей основной панели. В зависимости от меню, которое я нажимаю, я меняю центральную часть DLP. Например, я меняю либо на form1.ui.xml или к form2.ui.xml . В обеих этих формах реализован «маркер» для отображения сообщения об ошибке:

 <g:HTMLPanel ui:field="messageblock"/>
  

Я следую шаблону MVP (я использую EventBus для связи), и пока все работает отлично. Единственное, что я не могу понять, это как заменить содержимое messageblock . Или, чтобы быть более конкретным, как получить доступ к messageblock из моего MainPresenter. Основная идея, лежащая в основе этого материала, заключается в объединении обработки ошибок в одном докладчике…

Я ищу что-то вроде

 final Panel panel = DockLayoutPanel.get("messageblock");
panel.add(subwidget);
  

Я ценю каждый намек…

Ответ №1:

Вы можете либо сделать дисплей ответственным за отображение ошибки (создать некоторый интерфейс с renderError(Error) помощью метода), либо заставить дисплей возвращать HTMLPanel, в который что-то еще может отобразить ошибку (некоторый интерфейс с HTMLPanel getErrorPanel() помощью метода). Последнее ближе всего к тому, о чем вы говорите. Пусть Form1 и Form2 реализуют HasErrorPanel , а затем вызывают getErrorPanel().add(subWidget) .

Комментарии:

1. Спасибо за ответ, это был мой первый подход, но я обнаружил, что он тесно связан. При таком подходе я должен обрабатывать (Error) HTMLPanel вплоть до DockLayoutPresenter. Form1.Display -> Form1.Presenter -> DockLayoutPresenter. И это то же самое для каждой формы, которая должна иметь возможность отображать сообщение об ошибке.

Ответ №2:

Вот к какому выводу я пришел. Может быть, это поможет кому-то еще. Это основано на том, что рекомендовал Райли Ларк — спасибо Райли кстати.

RegistrationPresenter здесь отвечает за процесс регистрации и показывает регистрационную форму пользователю. Сообщение об ошибке должно отображаться как можно ближе к месту, где произошла ошибка.

Без ошибок http://www.mikemitterer.at/fileadmin/stacktrace_imagehosting/screenshot-778.jpg

Произошла ошибка: выскочила ошибка http://www.mikemitterer.at/fileadmin/stacktrace_imagehosting/screenshot-780.jpg

Вот примерное описание того, как я реализовал это поведение:

 public class RegistrationPresenter implements Presenter {

public interface Display extends StatusDisplay, HasMessageBlock {
    Widget asWidget();

    void setData(RegistrationTO registration);
}

private final Display   display;
private final EventBus  eventBus;
    ...
  

как вы можете видеть, на дисплее реализован HasMessageBlock:

 public interface HasMessageBlock {
void showMessage(Message message);

void hideMessage();
    }
  

Существует блок сообщений UiBinder-Widget (MessageBlock.ui.xml MessageBlock.java )
(messageblock будет превращен в невидимый в его конструкторе)

     <g:HTMLPanel styleName="errorblock" ui:field="messageblock">
        <div id="errorMsg" class="flurid">
            <div class="row">
                <div class="column width_15/16">
                    <h3><ui:msg key="errorblock.headline">An error occurred...</ui:msg></h3>
                </div>
                <div class="column orientation-right islink width_1/16">
                    <g:Image resource='{res.xgray}' ui:field="image" />
                </div>
     ...
  

Виджет регистрации теперь включает MessageBlock

 <g:HTMLPanel styleName="registration" ui:field="panel">
    <div class="uniForm maxgrid700">
        <h1>
            <ui:msg key="registration.headline">Registration</ui:msg>
        </h1>
        <c:MessageBlock ui:field="messageblock"/>
        <div class="ctrlHolder">
            <p class="label">
                <em></em>
                <ui:msg key="registration.name">Name:</ui:msg>
            </p>
     ...
  

Теперь, если кто-то отправляет сообщение

 eventbus.fireEvent(new MessageEvent(new MessageImpl(Message.MESSAGETYPE.ERROR, "Server Error Message")));
  

каждый докладчик, у которого есть «HasMessageBlock» для его отображения, может обработать / отобразить сообщение:

         eventBus.addHandler(MessageEvent.TYPE, new MessageEventHandler() {

        @Override
        public void execute(final MessageEvent event) {
            display.showMessage(event.getMessage());
        }
    });