2011-11-23 38 views
9

我正在使用GWT MVP和UiBinder創建一個帶有DockLayoutPanel的應用程序。我希望南北碼頭是靜態的,包含按鈕和鏈接。我希望在東碼頭的中心和兩個不同的區域有動態的視野。由於這些動態區域應該彼此獨立,因此我爲每個動態顯示區域設置了不同的ActivityMapper和ActivityManager;中心,東邊和東邊。如何:UiBinder + GWT MVP +多個獨立顯示區域

如何在應用程序加載時獨立初始化這3個不同的顯示區域?如何在一個顯示區域中從一個活動切換到另一個活動而不影響其他區域?

當我使用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

公共類MyModule的實現入口點{

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); 
    } 
} 

回答

9

GWT Place s,PlaceControllerPlaceHistoryMapper使您能夠在應用程序中創建可收藏的URL,以便讓瀏覽器的後退按鈕和書籤按預期工作。這是GWT Place的設計目的。因此,在任何時間點在應用程序中激活多個Place是沒有意義的,因爲您有一個整個應用程序的URL。

PlaceControllergoTo()方法確實通知註冊的ActivityManager,它會在接收到PlaceChangeEvent時停止當前活動。

我的建議是不要在DockLayoutPanel的東邊的兩個區域使用Place s和PlaceChangeEvent s。使用Place作爲您應用程序的主屏幕,這可能是您的DockLayoutPanel的中心。啓動不同的GwtEvent類型,當您需要更新東部區域時,可以使用其中一種通用事件類型(即。ValueChangeEvent)或自定義事件類型。您仍然可以在東側使用Activitie,但您需要創建自己的ActivityManager,這實際上並不難。您所要做的只是複製GWT的ActivityManager,重命名它,並將處理PlaceChangeEvent s和PlaceChangeRequestEvent s的方法的名稱替換爲處理您自己事件的方法的名稱。

+0

這正是我最終做的。謝謝! – Pete

1

你確定你真的想使用谷歌的MVP執行?易於使用mvp4g來實現此機制的故障。主模塊負責初始化主視圖並提供重新加載動態區域的邏輯。我在兩個大型項目中使用了這個框架,並且像魅力一樣工作。