如何:UiBinder + GWT MVP +多个独立显示区域

发布于 2024-12-17 13:35:50 字数 4833 浏览 4 评论 0原文

我正在使用 GWT MVP 和 UiBinder 创建带有 DockLayoutPanel 的应用程序。我希望南北码头是静态的,包含按钮和链接。我想要在中心和东码头的两个不同区域拥有动态视图。由于这些动态区域应该相互独立,因此我为每个动态显示区域设置不同的 ActivityMapper 和 ActivityManager;中心、东上、东下。

当应用程序加载时,如何独立初始化这3个不同的显示区域?如何在一个显示区域中从一个 Activity 切换到另一个 Activity 而不影响其他区域?

当我使用 PlaceController 的 goTo 从一个区域中的一个位置切换到另一个位置时,另一区域的 Activity 会停止。

五月天,请帮忙,五月天!

以下是我的一些代码:

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

public class MyModule Implements 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);
    }
}

I am using GWT MVP and UiBinder to create an app with a DockLayoutPanel. I want the north and south docks to be static, containing buttons and links. I want to have dynamic views in the center and two different areas of the east dock. As these dynamic areas should be independent of each other, I am setting up different ActivityMapper and ActivityManager's for each dynamic display area; center, east-top, and east-bottom.

How can I independently initialize these 3 different display areas when the application is loaded? How can I switch from one Activity to another in one display area without affecting the other areas?

When I use the the PlaceController's goTo to switch from one Place to another in one area, the other area's Activity is stopped.

Mayday, please help, mayday!

The following is some of my code:

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

public class MyModule implements 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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦言归人 2024-12-24 13:35:52

GWT PlacePlaceControllerPlaceHistoryMapper 使您能够在应用程序中创建可添加书签的 URL,从而允许浏览器的后退按钮和书签作为一个整体工作会期望。这就是 GWT Place 的设计目的。因此,在任何时间点在应用程序中激活多个 Place 是没有意义的,因为整个应用程序只有一个 URL。

PlaceControllergoTo() 方法会通知已注册的 ActivityManager,后者在收到 PlaceChangeEvent 后停止当前 Activity。

我建议您不要对 DockLayoutPanel 东侧的两个区域使用 PlacePlaceChangeEvent。使用 Place 作为应用程序的主屏幕,它可能是 DockLayoutPanel 的中心。当您需要时,为东侧的区域触发不同的 GwtEvent 类型,可以是通用事件类型之一(即 ValueChangeEvent)或自定义事件类型已更新。您仍然可以在东边使用 Activitie,但您需要创建自己的 ActivityManager,这实际上并不难。您所要做的就是复制 GWT 的 ActivityManager,将其重命名,并将处理 PlaceChangeEventPlaceChangeRequestEvent 的方法名称替换为这些方法的名称处理您自己的事件。

GWT Places, PlaceController, and PlaceHistoryMapper enable you to create bookmarkable URLs within your application that allow the browser's back button and bookmarks to work as one would expect. This is what GWT Places was designed for. Therefore it does not make sense to have more than one Place activated in an application at any point in time since you have one URL for the entire application.

PlaceController's goTo() method does notify the registered ActivityManager, which stops the current Activity upon receiving a PlaceChangeEvent.

My suggestion for you is not to use Places and PlaceChangeEvents for the two areas on the east side of your DockLayoutPanel. Use Places for your application's main screen, which is probably the center of your DockLayoutPanel. Fire different GwtEvent types, either one of the generic event types (ie. ValueChangeEvent) or a custom event type, for the areas on the east side when you need to have them updated. You could still use Activities for the east side, but you would need to create your own ActivityManager, which is actually not that hard. All you have to do is to copy GWT's ActivityManager, rename it, and replace the names of methods that handle PlaceChangeEvents and PlaceChangeRequestEvents with those that handle your own events.

ゃ懵逼小萝莉 2024-12-24 13:35:52

你确定你真的想使用谷歌的 mvp 实现吗?使用 mvp4g 实现此机制非常简单。主模块将负责初始化主视图并提供重新加载动态区域的逻辑。我在两个大型项目中使用了这个框架,并且效果非常好。

Are you sure you really want to use google's mvp implementation? It's failry easy to implement this mechanism using mvp4g. The main module would be responsible for initializing main view and providing logic to reload dynamic areas. I used this framework in two large projects and works like a charm.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文