ovirt gwt sub tab model 分析

在点击每个主model,下方会出现几个sub tab,如下图所示,在之前的文章中分析过每个Mianmodel 的XXlistModel 之间的关系。现在来分析下sub tab的 model 又究竟是怎么一回事?

135627_AqYF_2834932.png

以虚拟机的mainModel为例 ,选 中一个虚拟后,下方出现了8个sub tab,

    protected void initDetailModels()
    {
        super.initDetailModels();

        ObservableCollection<EntityModel> list = new ObservableCollection<EntityModel>();
        list.add(new VmGeneralModel());
        list.add(new VmInterfaceListModel());
        VmDiskListModel diskListModel = new VmDiskListModel();
        diskListModel.setSystemTreeContext(this);
        list.add(diskListModel);
        list.add(new VmSnapshotListModel());
        list.add(new VmEventListModel());
        list.add(new VmAppListModel());
        list.add(new PermissionListModel());
        list.add(new VmAffinityGroupListModel());
        list.add(new VmSessionsModel());
        setDetailModels(list);
    }

在VmlistModel,在构造方法中会调用 如上方法,初始化每个DetailMdoels的实例,以VmGeneralModel为例,该model就在ListModel中实例化,而该类中主要的逻辑为对用户行为的逻辑处理,如某个button,或者选中某个items 等。 
    而在所有的mainTab的Presenter的父类 AbstractMainTabWithDetailsPresenter中,在初始化时注册界面items change变化的handler,onBind实现如下

    @Override
    protected void onBind() {
        super.onBind();
        registerHandler(getTable().getSelectionModel()
                .addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
                    @Override
                    public void onSelectionChange(SelectionChangeEvent event) {
                        // Update main model selection
                        modelProvider.setSelectedItems(getSelectedItems());
                        // Let others know that the table selection has changed
                        fireTableSelectionChangeEvent();
                        // Reveal the appropriate place based on selection
                        handlePlaceTransition();
                    }
                }));
    }

 

1)首先调用model的setSelectedItems

在这一步中,

    public void setSelectedItem(T value)
    {
        if (selectedItem != value)
        {
            onSelectedItemChanging(value, selectedItem);
            selectedItem = value;
            onSelectedItemChanged();
            getSelectedItemChangedEvent().raise(this, EventArgs.EMPTY);
            onPropertyChanged(new PropertyChangedEventArgs("SelectedItem")); //$NON-NLS-1$
        }
    }

在onSelecttedItemChanged()方法中,

根据Activate的DeatilModel

activeDetailModel.setEntity(provideDetailModelEntity(getSelectedItem()));

而setEntity,就调用 

  public void setEntity(T value)
    {
        if (entity != value)
        {
            entityChanging(value, entity);
            entity = value;
            onEntityChanged();
            // EntityChanged(this, EventArgs.Empty);
            getEntityChangedEvent().raise(this, EventArgs.EMPTY);
            onPropertyChanged(new PropertyChangedEventArgs("Entity")); //$NON-NLS-1$
        }
    }

最终调用onEntityChanged()方法,从而调用具体subTab    model的updateProperity()

2)发布SelectionChangeEvent,

@Override
    protected void fireTableSelectionChangeEvent() {
        VirtualMachineSelectionChangeEvent.fire(this, getSelectedItems());
    }

 

  而在相应的subTab的 Presenter中,就是通过 

 @ProxyEvent
    public void onVirtualMachineSelectionChange(VirtualMachineSelectionChangeEvent event) {
        updateMainTabSelection(event.getSelectedItems());
    }

根据gwt注解相应的逻辑,从而调用subTab中的on**SelectionChange方法,如下 而后执行,最终调用view的 setMainTab方法,

   /**
     * Notifies this sub tab presenter that the main tab selection has changed.
     */
    protected void updateMainTabSelection(List<T> mainTabSelectedItems) {
        this.mainTabSelectedItems = mainTabSelectedItems;
        T firstSelectedItem = getMainTabSelectedItem();
        // Notify view of selection change
        if (firstSelectedItem != null) {
            getView().setMainTabSelectedItem(firstSelectedItem);
        }
    }

从而找到view的 方法

    @Override
    public void setMainTabSelectedItem(VM selectedItem) {
        form.update();
    }

3) 界面的显示渲染

protected void handlePlaceTransition() {
        if (hasSelection()) {
            // Sub tab panel is shown upon revealing the sub tab, in order to avoid
            // the 'flicker' effect due to the panel still showing previous content
            placeManager.revealPlace(getSubTabRequest());
        } else {
            // Hide sub tab panel when there is nothing selected
            setSubTabPanelVisible(false);
            placeManager.revealPlace(getMainTabRequest());
        }
    }

而后会发布 事件

  protected void doRevealPlace(PlaceRequest request, boolean updateBrowserUrl) {
        PlaceRequestInternalEvent requestEvent = new PlaceRequestInternalEvent(request,
                updateBrowserUrl);
        fireEvent(requestEvent);
        if (!requestEvent.isHandled()) {
            unlock();
            error(tokenFormatter.toHistoryToken(placeHierarchy));
        } else if (!requestEvent.isAuthorized()) {
            unlock();
            illegalAccess(tokenFormatter.toHistoryToken(placeHierarchy));
        }
    }

而对于Event的事件处理流程,简单要介绍下,

在Event的定义中,会定义一个对应handler的type,在注册时,key为type,value为handler。

    public static Type<PlaceRequestInternalHandler> getType() {
        if (TYPE == null) {
            TYPE = new Type<PlaceRequestInternalHandler>();
        }
        return TYPE;
    }

而fireEvent,通过EventBus,找到handler

  List<H> handlers = getDispatchList(event.getAssociatedType(), source);

而后通过 event的回调disaptcher,从而执行handler的方法。

  protected static <H> void dispatchEvent(Event<H> event, H handler) {
    event.dispatch(handler);
  }

 

Handler的注册

而针对 上述的handler是在何处注册,这就涉及到gwt的代理的机制,在该类中注册
ProxyPlaceAbstract,如下,就着就会处理相应的事件。

  @Inject
    protected void bind(final PlaceManager placeManager, EventBus eventBus) {
        this.placeManager = placeManager;
        this.eventBus = eventBus;

        addRegisteredHandler(PlaceRequestInternalEvent.getType(), new PlaceRequestInternalHandler() {
            @Override
            public void onPlaceRequest(PlaceRequestInternalEvent event) {
                if (event.isHandled()) {
                    return;
                }
                PlaceRequest request = event.getRequest();
                if (matchesRequest(request)) {
                    event.setHandled();
                    if (canReveal()) {
                        handleRequest(request, event.shouldUpdateBrowserHistory());
                    } else {
                        event.setUnauthorized();
                    }
                }
            }
        });

接着往下跟会发现,而这里的proxy,就是P中的成员 proxyDef. 最终将subTab的页面显示出来。

 

 

 

转载于:https://my.oschina.net/ovirtKg/blog/744477

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值