Как: 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);
    }
}

person Pete    schedule 23.11.2011    source источник


Ответы (2)


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

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

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

person Cengiz    schedule 25.11.2011
comment
Это именно то, чем я закончил. Спасибо! - person Pete; 26.11.2011

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

person beastieboy    schedule 24.11.2011