如何在ovirt中使用GWT框架为页面新增组件
Ovirt中的GWT框架(GWTP)
参考 ovirt gwt 代码分析
如何要在GWT页面新增或者修改组件?
修改、新增、删除菜单可以参考文档 增加/修改左侧导航
定位页面
ovirt中的页面明规则,ovirt页面
以集群为例- 集群列表页面
MainClusterView.java(V) 类似页面为 MainNetworkView.java MainHostView.java - tab页面
SubTabClusterGeneralView.java 类似页面为SubTabHostGeneralView.java 新建、删除、修改等各种按钮监听页面
ClusterPopupView.java 类似页面为 HostPopupView.java要想找到这些页面可以通过该页面名称在PresenterModule.java页面中进行查询,PresenterModule 中定义了每个 tab、popubview 的 M、V、P 三者之间的关系。
- 集群列表页面
修改页面
定位页面后,可以对页面进行操作,比如新增、修改、隐藏某个组件。注意如果view页面有对应的xml页面,修改时需要将两个文件内容同步。
以下以在新建、编辑虚拟网卡配置集页面中新增安全组下拉列表为例- 按照以上方法对页面进行定位,找到需要修改页面 VnicProfilePopupView.java
且可以发现VnicProfilePopupView.java存在对应VnicProfilePopupView.ui.xml中存在各种引用 - 在页面中新增安全组单选组件
VnicProfilePopupView.ui.xml
在VnicProfilePopupView.ui.xml中存在各种引用<ui:UiBinder <!-- GWT组件 提供可以引用的组件(GWT原生、GWTbootstrap3、ovirt原生) --> xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:d="urn:import:org.ovirt.engine.ui.common.widget.dialog" xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor" xmlns:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic" xmlns:k="urn:import:org.ovirt.engine.ui.common.widget.form.key_value" xmlns:b="urn:import:org.gwtbootstrap3.client.ui"> <!-- 引用应用常量,一般设置组件名称 --> <ui:with field='constants' type='org.ovirt.engine.ui.webadmin.ApplicationConstants' />
建议使用原生,及框架中的已知简单组件,可以在网上查询文档进行参考
<b:Row> <e:ListModelListBoxEditor ui:field="securityGroupsEditor" label="{constants.safeGroup}" usePatternFly="true" labelColSize="SM_6" widgetColSize="SM_6" /> </b:Row>
<e />
: 组件所在库
ListModelListBoxEditor
:组件名称
ui:field="securityGroupsEditor
": 该参数需要和view中保存相同
label="{constants.safeGroup}"
: 组件显示名称
labelColSize="SM_6" widgetColSize="SM_6"
: 组件样式
还可以在xml中新增css样式<ui:style> .firstRow { padding-top: 15px; } .hide_ext { display: none; } </ui:style> <b:Row addStyleNames="{style.hide_ext}"> <b:Column size="SM_12" > <g:Label text="{constants.customPropertiesVnicProfile}" /> </b:Column> </b:Row>
声明的css可以使用addStyleNames="{style.hide_ext}"添加到组件上
VnicProfilePopupView.java
增加名称为xml中ui:field值的参数,类型对应所使用的的组件@UiField(provided = true) @Path("securityGroups.selectedItem") public ListModelListBoxEditor<SecurityGroupForVnic> securityGroupsEditor;
在构造方法中对组件进行初始化
securityGroupsEditor = new ListModelListBoxEditor<>(new SecurityGroupForVnicRenderer(constants));
VnicProfileModel.java NewVnicProfileModel.java EditVnicProfileModel.java
NewVnicProfileModel、EditVnicProfileModel继承了VnicProfileModel,相同操作在VnicProfileModel中实现。相同操作
声明对象,用来保存后台查到的值,以及名称需要对应view页面中@Path("securityGroups.selectedItem")
中securityGroups
//过滤从后台查来的值,使其符合组件对应数据格式 private ListModel<SecurityGroupForVnic> securityGroups; public ListModel<SecurityGroupForVnic> getSecurityGroups() { return securityGroups; } public void setSecurityGroups(ListModel<SecurityGroupForVnic> securityGroups) { this.securityGroups = securityGroups; } //用来存取后台查询的值 List<ExtSecurityGroupForCreate> securitys; public List<ExtSecurityGroupForCreate> getSecuritys() { return securitys; } public void setSecuritys(List<ExtSecurityGroupForCreate> securitys) { this.securitys = securitys; }
声明空选项,下拉列表设置空选项
private static final SecurityGroupForVnic EMPTY_SECURITY = new SecurityGroupForVnic();
在构造方法中对数据进行初始化
// 初始化下拉列表值 setSecurityGroups(new ListModel<SecurityGroupForVnic>()); //请求后台,查询安全局数据 querySecurityGroupList();
Frontend.getInstance().runQuery()
: 请求后台接口方法
QueryType.GetAllSecurityGroup
: 后台请求query, 后台实现为GetAllSecurityGroupQuery
new SecurityGroupQueryParameter(0, null)
: 查询参数
new AsyncQuery<QueryReturnValue>()
: 接口请求回调,在该方法中向securitys
赋值public void querySecurityGroupList(){ Frontend.getInstance().runQuery(QueryType.GetAllSecurityGroup, new SecurityGroupQueryParameter(0), new AsyncQuery<QueryReturnValue>(returnValue -> { if (returnValue != null) { setSecuritys(returnValue.getReturnValue()); } })); }
在安全组改变事件中增加
initSecurityGroups()
getDataCenters().getSelectedItemChangedEvent().addListener((ev, sender, args) -> { if (getDataCenters().getSelectedItem() != null) { Version dcCompatibilityVersion = getDataCenters().getSelectedItem().getCompatibilityVersion(); Guid currentDcId = getDataCenters().getSelectedItem().getId(); initCustomPropertySheet(dcCompatibilityVersion); initNetworkQoSList(currentDcId); initNetworkFilterList(dcCompatibilityVersion); initNetworkList(currentDcId); //该方位为重新初始化安全组下拉列表值 initSecurityGroups(); } });
该方法对安全组下拉列表进行值的初始化
private void initSecurityGroups(){ if (!getSecurityGroups().getIsAvailable()) { return; } querySecurityGroupList(); if (getSecuritys() != null){ List<SecurityGroupForVnic> securityGroupForVnics = new ArrayList<>(); securityGroupForVnics.add(EMPTY_SECURITY); getSecuritys().stream() .filter(sg -> getDataCenters().getSelectedItem() != null && getDataCenters().getSelectedItem().getId().toString().equals(sg.getDataCenterId())). forEach(sg -> { SecurityGroupForVnic securityGroupForVnic = new SecurityGroupForVnic(); securityGroupForVnic.setId(Guid.createGuidFromString(sg.getId())); securityGroupForVnic.setName(sg.getName()); securityGroupForVnics.add(securityGroupForVnic); }); getSecurityGroups().setItems(securityGroupForVnics); initSecurityGroupsValue(); } }
保存时页面参数封装,把当前选中的值放到保存参数中
SecurityGroupForVnic selectedItem = getSecurityGroups().getSelectedItem(); if (selectedItem != null && selectedItem.getId() != null && !selectedItem.getId().equals(Guid.Empty)){ Map<String ,String> sgs = new HashMap<>(); sgs.put("SecurityGroups", selectedItem.getId().toString()); //$NON-NLS-1$ vnicProfile.setCustomProperties(sgs); }else { vnicProfile.setCustomProperties(null); }
差异
NewVnicProfileModel.java
中需要将当前下拉列表中的值选中空选项@Override protected void initSecurityGroupsValue() { // Do nothing getSecurityGroups().setSelectedItem(Linq.firstOrNull(getSecurityGroups().getItems(), new Linq.NamePredicate(null))); }
EditVnicProfileModel.java
需要将已选中的值渲染到下拉列表中@Override protected void initSecurityGroupsValue() { if(getProfile().getCustomProperties() != null && getProfile().getCustomProperties().get("SecurityGroups") != null){ getSecurityGroups().setSelectedItem(Linq.firstOrNull(getSecurityGroups().getItems(), new Linq.IdPredicate<>(Guid.createGuidFromString(getProfile().getCustomProperties().get("SecurityGroups"))))); } }
- 按照以上方法对页面进行定位,找到需要修改页面 VnicProfilePopupView.java
注意点
frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
ovirt中如果想用backend创建的实体类,需要在该文件中进行声明
<include name="common/businessentities/network/securitygroups/ExtSecurityGroupForCreate.java"/> <include name="common/businessentities/network/securitygroups/ExtSecurityGroupRuleForCreate.java"/> <include name="common/businessentities/network/securitygroups/SecurityGroupForVnic.java"/> <include name="common/action/securitygroup/SecurityGroupQueryParameter.java" />
总结
该文档只说明前台新建GWT组件时,需要做的操作,具体页面、具体功能需要根据实际进行设计
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。