最近(2017年10月26日)在開發MES項目。使用的是Ext3.3.1。
下圖是我的需求(實際上是已經做好的)~
需求是一個分欄頁面,左側為菜單欄,右側是數據面板。要求根據用戶在左側選擇的不同菜單,右側改變為相應的數據面版。
在使用Ext編寫這段需求時遇到了如下一些困難,逐一解決后,將經驗在這里分享下。
經驗一 : 關于BorderLayout中增刪組件
從需求中可以看出使用BORDER布局最為合適,west區域為菜單欄,準備使用Ext的Menu控件,center區域為數據面板。
使用中需要注意下面的這些問題(來自于Ext3 API):
Notes:
- Any container using the BorderLayout must have a child item with region:'center'. The child item in the center region will always be resized to fill the remaining space not used by the other regions in the layout.
- Any child items with a region of west or east must have width defined (an integer representing the number of pixels that the region should take up).
- Any child items with a region of north or south must have height defined.
- The regions of a BorderLayout are fixed at render time and thereafter, its child Components may not be removed or added. To add/remove Components within a BorderLayout, have them wrapped by an additional Container which is directly managed by the BorderLayout. If the region is to be collapsible, the Container used directly by the BorderLayout manager should be a Panel.
注意引文中的粗體字,即BorterLayout布局中,每個區域的組件不能刪除或增加。我在開發中,一開始想的是在換菜單時,如從“計劃缺料異?!秉c到“訂單交期異常”,中間面板(centerPanel)的操作是,先刪除所有組件。
this.removeAll();
再添加
this.add(...);
如上所述,這個做法是行不通的。中間的組件刪除后,面板變空,任我如何添加,都不能把新的組件渲染到頁面上去。
正確的做法,寫在上文的斜體字中。即在Center區域中增加一個Panel。Layout為Auto,或者Box的等,只要不是Border的就行。然后將需要添加和刪除的組件new到這個Panel的items里。
//這里定義centerPanel
this.centerPanel = new Ext.Panel({
id : 'centerPanel',
layout: {
type: 'hbox',
align: 'stretch'
},
region : 'center',
renderTo: Ext.getCmp('main'),
//item中的組件要重新New,傳參會shallow copy
items: [
new rs.mpm.planImpStatus.planLackM.GridPanel({
id : 'planLackMPanel',
title : '計劃缺料異常',
flex: 100
})
]
});
//這里是點擊菜單事件的監聽器
fn: function(item,e) {
// 點擊某個菜單項,將該菜單項背景顏色加深
item.addClass('item_actived');
Ext.getCmp('orderDeliveryItem').removeClass('item_actived');
Ext.getCmp('preparationItem').removeClass('item_actived');
// 去除centerPanel中的面板,換成與該菜單項相對應的面板
this.centerPanel.removeAll();
this.centerPanel.add(
new rs.mpm.planImpStatus.planLackM.GridPanel({
id : 'planLackMPanel',
title : '計劃缺料異常',
})
);
this.centerPanel.doLayout();
}
在定義的centerPanel中,就可以完美的進行添加刪除組件了。
經驗二 : 在Ext中添加樣式,即使用CSS
Ext的組件都是封裝過了,這樣雖然使用起來方便,但是遇到特殊的需求時,比如說更改為某個特定的樣式,這類問題就比較棘手。
例如,這個需求需要在點擊后將按鈕的背景顏色變深。CSS很好寫:
.x-menu-item.menu_item{
color:black!important;
font-size: larger;
}
.item_actived{
background-color :#D0DEF0
}
.item_margin{
margin-bottom: 10px
}
ps:第一段CSS是設置菜單字體的。字體顏色的設置為了抵消掉項目中的maincss.css需要加上!important才能生效
問題的關鍵是如何正確使用CSS屬性將這段CSS添加到正確的位置。因為你用EXT組件寫前端,是接觸不了HTML的嘛。
EXT代碼:
this.menuPanel = new Ext.menu.Menu({
region : 'west',
width : 220,
plain: true,
floating: false,
style : "padding-top:10px",
items : [
{
id : 'planLackMItem',
text: '計劃缺料異常',
//針對該菜單項的CSS <a>
cls : 'menu_item',
//針對包含菜單項的容器的CSS <li>
ctCls : 'item_margin',
listeners :
......
整個Menu組件轉化的HTML代碼如上圖所示,簡要來說div中包含ul
<div><!-- Menu組件以DIV標簽開始 -->
<ul>
<li>
<a><!-- 這里才是你定義的ITEM-->
...
所以有的時候你需要在a標簽上添加樣式,但有的樣式需要添加在li上,這分別要如何操作呢?
Ext中對于一般組件來說,添加樣式的屬性有以下幾種(以為Menu中的Item組件添加為例)
1、style屬性,這個屬性會直接添加到a標簽中。
有兩種寫法,一種為JSON格式:
{
width: '95%',
marginBottom: '10px'
}
注意,此處的STYLE屬性為EXT中定義的,并不和CSS相同。
另一種寫法為字符串式的
"padding-top:10px"
引號中的內容會直接加到對象的style屬性中。這種方法操作起來很方便。
2、cls屬性
這個屬性的內容會添加到標簽的class屬性中,即其中寫CSS的選擇器的名字就可以了。對于item組件,即為<a>標簽的class屬性。
3、ctCls屬性
這個也是將屬性內容添加到標簽的class屬性中,但與cls不同的是,添加到容器的標簽。對于item組件,將添加到<li>標簽的class屬性中。
4、itemCls屬性
這個屬性和cls類似,但會直接改變<a>標簽中的內容,而不僅僅是添加。