Как: UiBinder + GWT MVP + несколько независимых областей отображения

Я использую GWT MVP и UiBinder для создания приложения с DockLayoutPanel. Я хочу, чтобы северные и южные доки были статичными, содержали кнопки и ссылки. Я хочу иметь динамические виды в центре и двух разных районах восточной пристани. Поскольку эти динамические области должны быть независимы друг от друга, я настраиваю различные ActivityMapper и ActivityManager для каждой динамической области отображения; центр, восток сверху и восток снизу.

Как я могу независимо инициализировать эти 3 различные области отображения при загрузке приложения? Как я могу переключиться с одного занятия на другое в одной области отображения, не затрагивая другие области?

Когда я использую goTo PlaceController для переключения с одного места на другое в одной области, активность другой области останавливается.

Mayday, пожалуйста, помогите, Mayday!

Ниже приводится часть моего кода:

AppViewImpl.ui.xml

<g:DockLayoutPanel styleName="{style.dockPanel}" unit="PX" width="975px" height="100%">

    <!-- DOCK PANEL EAST -->
    <g:east size="220">
        <g:LayoutPanel styleName="{style.eastPanel}">
            <g:layer left="0px" width="220px" top="0px" height="105px">
                <g:SimpleLayoutPanel ui:field="topRightPanel"/>
            </g:layer>

            <g:layer left="0px" width="220px" top="110px" height="340px">
                    <g:InlineLabel styleName="{style.label}" text="ANOTHER DISPLAY AREA"/>
            </g:layer>
        </g:LayoutPanel>
    </g:east>

    <!-- DOCK PANEL NORTH -->
    <g:north size="110">
        <g:LayoutPanel styleName="{style.northPanel}">
            <g:layer left="0px" width="755px" top="0px" height="105px">
                    <g:InlineLabel styleName="{style.label}" text="NORTH PANEL"/>
            </g:layer>
        </g:LayoutPanel>
    </g:north>

    <!-- DOCK PANEL SOUTH -->
    <g:south size="20">
        <g:LayoutPanel styleName="{style.southPanel}">
            <g:layer left="0px" width="755px" top="0px" height="20px">
                    <g:InlineLabel styleName="{style.label}" text="SOUTH PANEL"/>
            </g:layer>
        </g:LayoutPanel>
    </g:south>

    <!-- DOCK PANEL CENTER -->
    <g:center>
        <g:SimpleLayoutPanel ui:field="mainPanel" />
    </g:center>
</g:DockLayoutPanel>

MyModule.java

открытый класс MyModule реализует EntryPoint {

private Place defaultPlace = new DefaultPlace("");

public void onModuleLoad() {
    // Create ClientFactory using deferred binding so we can replace with 
    // different impls in gwt.xml
    ClientFactory clientFactory = GWT.create(ClientFactory.class);
    EventBus eventBus = clientFactory.getEventBus();
    PlaceController placeController = clientFactory.getPlaceController();

    // Start ActivityManager for the main widget with our ActivityMapper
    ActivityMapper topRightActivityMapper = new TopRightActivityMapper(clientFactory);
    ActivityManager topRightActivityManager = new ActivityManager(topRightActivityMapper, eventBus);
    topRightActivityManager.setDisplay(clientFactory.getAppView().getTopRightPanel());

    // Start ActivityManager for the main widget with our ActivityMapper
    ActivityMapper mainActivityMapper = new AppActivityMapper(clientFactory);
    ActivityManager mainActivityManager = new ActivityManager(mainActivityMapper, eventBus);
    mainActivityManager.setDisplay(clientFactory.getAppView().getMainPanel());

    // Start PlaceHistoryHandler with our PlaceHistoryMapper
    AppPlaceHistoryMapper historyMapper = GWT .create(AppPlaceHistoryMapper.class);
    PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
    historyHandler.register(placeController, eventBus, defaultPlace);
    RootLayoutPanel.get().add(clientFactory.getAppView());

    // Goes to place represented on URL or default place
    historyHandler.handleCurrentHistory();

    new AppController(clientFactory);
}

}

AppController.java

public class AppController implements AppView.Presenter {

    private ClientFactory clientFactory;

    AppController(ClientFactory clientFactory){
        this.clientFactory = clientFactory;
        goTo(new TopRightAPlace(""));
    }

    @Override
    public void goTo(Place place) {
        clientFactory.getPlaceController().goTo(place);
    }

}

TopRightAViewImpl.java

public class TopRightAViewImpl extends Composite implements TopRightAView {

    interface Binder extends UiBinder<Widget, TopRightAViewImpl> {
    }

    private static final Binder binder = GWT.create(Binder.class);

    private Presenter listener;
    @UiField
    Button button;

    public TopRightAViewImpl() {
        initWidget(binder.createAndBindUi(this));
    }

    @Override
    public void setName(String name) {
        button.setHTML(name);
    }

    @Override
    public void setPresenter(Presenter listener) {
        this.listener = listener;
    }

    @UiHandler("button")
    void onButtonClick(ClickEvent event) {
        listener.goTo(some other place);
    }
}

2 ответа

Решение

GWT Places, PlaceController, а также PlaceHistoryMapper Позволяет вам создавать закладки URL в вашем приложении, которые позволяют кнопке браузера назад и закладкам работать так, как вы ожидаете. Это то, что GWT PlaceS был разработан для. Поэтому не имеет смысла иметь более одного Place активируется в приложении в любой момент времени, поскольку у вас есть один URL для всего приложения.

PlaceController"s goTo() метод уведомляет зарегистрированных ActivityManager, который останавливает текущую активность после получения PlaceChangeEvent.

Мое предложение для вас не использовать Placeс и PlaceChangeEvents для двух областей на восточной стороне вашего DockLayoutPanel, использование Places для основного экрана вашего приложения, которое, вероятно, является центром вашего DockLayoutPanel, Огонь разный GwtEvent типы, один из общих типов событий (т. е. ValueChangeEvent) или пользовательский тип события, для областей на восточной стороне, когда вам нужно обновить их. Вы все еще можете использовать Activitieдля восточной стороны, но вам нужно будет создать свой собственный ActivityManagerчто на самом деле не так сложно. Все, что вам нужно сделать, это скопировать GWT ActivityManager, переименуйте его и замените имена методов, которые обрабатывают PlaceChangeEventс и PlaceChangeRequestEventс теми, которые обрабатывают ваши собственные события.

Вы действительно хотите использовать реализацию Google MVP? Легко реализовать этот механизм с помощью mvp4g. Основной модуль будет отвечать за инициализацию основного представления и предоставление логики для перезагрузки динамических областей. Я использовал этот фреймворк в двух крупных проектах и ​​работает как шарм.

Другие вопросы по тегам