Buttons and Toolbars

在本章,你將學習到如何創建buttons和toolbars, 以及如何處理事件,使用戶可以跟Ext JS UI進行交互

Event-driven development

在我們學習組件之前,我們需要明白背後的event和listeners是如何工作的。首先你要學習什麼是觀察者模式(observable pattern).

簡單來講,觀察者模式是允許實體或者對像,彼此使用事件進行通信。當某個行爲發生在一個對像或者組件上,這個對像應該廣播這個事件給它的監聽者。

舉例來說,當一個button被點擊後,它觸發一個click事件。當grid的一行被點擊,grid觸發itemclick事件。所有的組件都定義了事件,它們在一個行爲出現時觸發。

觸發事件的組件並不知道誰監聽了它的消息,它的職責只是讓別人知道發生了什麼。然後,其它組件才做出相應的處理,或者什麼也不做

Ext.util.Obserable,這個基礎類允許我們從一個指定的對像或者組件中,添加,觸發,監聽事件。並且當事件發生時,執行相應的行爲。

Ext JS library中的所有widget 都混合了Ext.util.Observable類,因此所有的widgets,都可以觸發和監聽事件

通過Ext.util.Observable, 我們可以在自定義組件上,定義和 觸發一個新的事件。如下所示

Ext.define('Myapp.sample.Employee',{
    mixins: {observable: 'Ext.util.Observable'},
    Code.....
    constructor: function( config ){
        Code.....
        this.mixins.observable.constructor.call( this, config );
    },
    quitJob: function(){
        this.fireEvent('quit', this.getName(), new Date(), 2,
            1, 'more params...' );
    }
});

在上面的代碼中,Employee類包含了mixin -Ext.util.Observable類。因此,在constructor函數中,可以通過this.mixins.observable.constructor.call(this, config)進行初始化。這就意味着,Ext.util.Observable將能夠注意在employee類中任何時候發生的任何事件。

瞭解更多mixins,可以查看http://docs.sencha.com/extjs/5.1/5.1.1-apidocs/#!/api/Ext.Mixin

當quitJob函數被調用時,它將觸發一個quit事件,並且傳遞this.getName(), new Date, 2, 1, ‘more params’參數.

在之前的Ext JS版本中,我們通過addEvent(…)方法創建或者定義這個類的事件。如果你從版本4升級過來,你需要注意這個改變。Version 5 具有更好的靈活性。

現在我們需要監聽’quit’事件。在Ext JS 中,我們有一個 listeners屬性,它就是用於這個目的(listen/handle events).

var patricia = Ext.create('Myapp.sample.Employee', {
   name:'Patricia',
   lastName:'Diaz',
   age:21,
   isOld:false,
   listeners:{
       'quit':function(EmployeeName, quitDate, param, paramb, paramc){
           console.log('Event quit launched');
           console.log('Employee:' + EmployeeName);
           console.log('Date:'+ Ext.util.Format.date(
                           quitDate,'Y-m-d H:i'));
           console.log('Param :' + param);
           console.log('Param B:' + paramb);
           console.log('Param C:' + paramc);
       }
   }
});
console.log(Myapp.CompanyConstants.welcomeEmployee(patricia));
    patricia.quitJob();
});

另一個常用的方法是使用on方法來監聽事件,它是addListener 縮寫

patricia.on({
    'quit':function(EmployeeName, quitDate, param, paramb, paramc){
        console.log('Event quit launched');
        console.log('Employee:' + EmployeeName);
        console.log('Date:' + Ext.util.Format.date(quitDate,
        'Y-m-d H:i'));
        console.log('Param :' + param);
        console.log('Param B:' + paramb);
        console.log('Param C:' + paramc);
    }
});
patricia.quitJob();

非常重要的一點是監聽器要在期望執行的方法之前添加. 在我們上面的例子中,Employee類在調用quitJob方法時,只負責廣播事件。這個類自己不關心誰監聽了quit事件。但在這個類之外,定義了一個對像,它監聽了這個事件。

在Ext JS中可以添加,觸發,監聽自定義事件是它非常強大的一個特性

Creating a simple button

現在你基本知道如何處理事件,現在我們開始使用component和widgets. 我們從button開始講起。爲了創建按紐,我們將需要使用Ext.button.Button類。讓我們創建第一個button.

var myButton = Ext.create('Ext.button.Button', {
    text:'My first button',
    tooltip:'Click me...!',
    renderTo:Ext.getBody()
});

在這段代碼中,我們創建了一個Button類的實例,並且傳遞了一些配置給它。通常一個button有許多的配置。
text屬性用於設置button渲染在document時,顯示的文本(DOM).
renderTo屬性允許我們設置按鈕在DOM中渲染的位置

這裏寫圖片描述

默認情況下,button有一個scale屬性的值爲small. 我們可以將它設置爲medium和large. scale屬性使得我們可以定義按鈕的大小。

var myButton = Ext.create('Ext.button.Button', {
    text:'My first small button',
    scale:'small',
    renderTo:Ext.getBody()
});
var myButtonB = Ext.create('Ext.button.Button', {
    text:'My first medium button',
    scale:'medium',
    renderTo:Ext.getBody()
});
var myButtonC = Ext.create('Ext.button.Button', {
    text:'My first large button',
    scale:'large',
    renderTo:Ext.getBody()
});

Setting icons on buttons

我們在應用程序中經常看到,使用不同的icons來區分按紐。爲了設置icon(images),我們將使用iconCls屬性來設置css樣式,它將以背景的形式,添加圖片。在上面的代碼中,我們討論過scale屬性,它分別對應以下的icon size

Scale Size
Small 16 x 16 pixels
Medium 24 x 24 pixels
Large 32 x 32 pixels

接下來,我們在html中創建以下css樣式

.addicon-16{
    background:transparent url('images/add_16x16.png') center 0
    no-repeat !important;
}
.addicon-24{
    background:transparent url('images/add_24x24.png') center 0
    no-repeat !important;
}
.addicon-32{
    background:transparent url('images/add_32x32.png') center 0
    no-repeat !important;
}

JS代碼

var myButton = Ext.create('Ext.button.Button', {
    text:'My first small button',
    iconCls:'addicon-16',
    scale:'small',
    renderTo:Ext.getBody()
});
var myButtonB = Ext.create('Ext.button.Button', {
    text:'My first medium button',
    iconCls:'addicon-24',
    scale:'medium',
    renderTo:Ext.getBody()
});
var myButtonC = Ext.create('Ext.button.Button',{
    text:'My first large button',
    iconCls:'addicon-32',
    scale:'large',
    renderTo:Ext.getBody()
});

Icon alignment on buttons

默認情況下, icon是左邊對齊的。但我們可以設置它的位置爲top, buttom, 和右側對齊。如下所示

var myButtonA = Ext.create('Ext.button.Button',{
    text:'left icon',
    iconCls:'addicon-16',
    iconAlign:'left',
    renderTo:Ext.getBody()
});
var myButtonB = Ext.create('Ext.button.Button',{
    text:'top icon',
    iconCls:'addicon-16',
    iconAlign:'top',
    renderTo:Ext.getBody()
});
var myButtonC = Ext.create('Ext.button.Button',{
    text:'right icon',
    iconCls:'addicon-16',
    iconAlign:'right',
    renderTo:Ext.getBody()
});
var myButtonD = Ext.create('Ext.button.Button',{
    text:'bottom icon',
    iconCls:'addicon-16',
    iconAlign:'bottom',
    renderTo:Ext.getBody()
});

這裏寫圖片描述

Handling button events

創建完一個按鈕後,我們想要在點擊時,添加一些行爲。在以後的章節中,我們將看到如何在MVVM模式中,監聽事件。對於現在,我們可以直接監聽 button上的事件。

Button通過mixin使用了Observable類,我們可以使用addListener方法監聽事件

每一個組件有許多已經定義好的事件。你可以查看document瞭解定義了哪些事件,事件何時觸發的描述,以及監聽器會接受到的參數。在這裏,Button類包含了一個click event, 它在button被點擊時觸發。我們可以使用on(addListener方法的簡寫)來監聽事件.

myButtonA.on('click', function(){
    Ext.Msg.alert("Click event", "You clicked left icon button..!");
});

我們還有更多的事件可以監聽,比如show,hide,enable, disable等等,更多的事件名稱,可以參考Ext JS文檔

我們可以爲相同的事件,定義任意多的監聽器,當事件觸發時,所有的監聽器都將被執行.

Segmented buttons

在Ext JS 5添加了一個 segemented buttons. 可以對組件進行分組。實際上,它是一個特殊的容器,包含多個按鈕。爲此,我們需要使用Ext.button.Segmented類,它的用法跟任何其它container的使用類似。

var mySegmentedbuttons = Ext.create('Ext.button.Segmented',{
    renderTo:'segmentedbuttons',
    vertical:false,
    items:[{
        xtype: 'button', text:'1st button', iconCls:'addicon-16'
    },{
        text:'2nd button', iconCls:'addicon-16'
    },{
        text:'3th button', iconCls:'addicon-16'
    },{
        text:'4th button', iconCls:'addicon-16'
    }]
});

這裏寫圖片描述

你會注意到,上圖中的第二行按鈕是以segmented button容器的形式渲染的,它比第一行看起來更美觀,對比於第一行的按鈕,第二行的按鈕只有第一個和最後一個帶圓角。

我們也可以設置vertical爲true, 效果如下

這裏寫圖片描述

默認情況下,Ext.button.Segmented類將它每一個項(item)視爲一個按鈕。在上面的代碼中,我們設置爲第一個按鈕設置了xtype屬性,其它三個按鈕則沒有這個屬性。Ext JS依然將每一個項作爲button進行配置。

Adding menus

我們可以爲button添加menu履性,創建菜單,使用戶可以選擇不同的選項。

var myButton = Ext.create('Ext.button.Button',{
    text:'Add payment method...',
    iconCls:'addicon-32',
    iconAlign:'left',
    scale:'large',
    renderTo:'normalbuttons',
    menu:[
        {text:'Master Card'},
        {text:'Visa'},
        {text:'PayPal'},
        {text:'Other...'}
    ]
});

在上面的代碼中, menu屬性接收一個對像數組。這個數組用於創建Ext.menu.Menu類的實例。Ext.menu.Menu類負責管理和顯示菜單。

這裏寫圖片描述

在上面的代碼中,我們是直接使用對像常量創建我們的菜單。如果你想使用構告函數,而不是直接量(literals), 我們應該創建Ext.menu.Menu和Ext.menu.Item的實例,如下所示

//Step 1
var menuItemA = Ext.create('Ext.menu.Item',{text:'Master card'});
//Step 2
var menu = Ext.create('Ext.menu.Menu',{
    items : [ //Step 3
        menuItemA, // Variable
        Ext.create('Ext.menu.Item',{text:'Visa'}), // constructor
        {text:'Paypal'} //object config
    ]
});
var myButton = Ext.create('Ext.button.Button',{
    text:'Add payment method...',
    iconCls:'addicon-32',
    iconAlign:'left',
    scale:'large',
    renderTo:'normalbuttons',
    menu:menu
});

當我們創建完menu, 我們將它賦值給button的menu屬性。當這個按鈕創建時,它會發現menu屬性不是一個數組,而是一個Menu類的實例。

接下來,我們可以爲每一個菜單項添加監聽器,查看Ext.menu.Item類的文檔,我們可以知道,它有一個click 事件, 在這裏我們有很多的方法來添加監聽器.

var myButton = Ext.create('Ext.button.Button',{
    text:'Add payment method...',
    iconCls:'addicon-32',
    iconAlign:'left',
    scale:'large',
    renderTo:'normalbuttons',
    menu:[{
        text:'Master Card',
        listeners:{ // Option 1
            click:function(){
                Ext.Msg.alert("Click event", "You selected Master Card..!");
            }
        }
    },{
        text:'Visa', //Option 2
        handler: onMenuItemClick
    },{
        text:'PayPal',
        listeners:{ //Option 3
            'click':{fn: onMenuItemClick , single:true}
        }
    },{
        text:'Other...',
        handler: onMenuItemClick
    }]
});
function onMenuItemClick (itemBtn, Event){
    var optionString = itemBtn.text;
    Ext.Msg.alert("Click event","You selected " + optionString +
            " ..!");
}
  1. Option 1, 我們添加了一個listeners屬性
  2. Option 2, 我們使用hander屬性,這個屬性將click event綁定到onMenuItemClick
  3. Option 3, 我們在次使用listeners屬性,但對於click event.我們傳遞了一個配置對像,它有兩個屬性:fn 和 single。fn屬性用於指定處理函數。single用於指定處理函數只執行一次,在第一次執行完後,Ext JS將刪除這個處理函數

Toolbars

我們已經學習了基礎的button和menus後,接下來可以學習下一個組件,toolbar. 工具欄在我們的應用程序中非常普遍,它用來訪問應用程序的modules, windows等等。toolbar組件實際上是一個容器,可以按照我們需要的方法排列我們的按鈕。

從Ext JS 4開始,我們可以在容器的任一方向(north, south, east and west)上定義toolbar. 也可以在container的每邊上都定義一個toolbar.

接下來我們創建一個簡單的例子,toolbar位於panel的top位置。

var myPanel = Ext.create( 'Ext.panel.Panel' ,{
    title: 'My first toolbar...',
    width: 450,
    height: 200,
    dockedItems: [{ //Step 1
        xtype : 'toolbar',
        dock: 'top', //Step 2
        items: [
            {text: 'New record'},
            {text: 'Edit record'},
            {text: 'Remove record'}
        ]
    }],
    renderTo:Ext.getBody()
});
  1. 在第一步,我們定義了dockedItems屬性。在這個屬性裏,我們可以定義一個組件數組。任何的組件可以固定(placed) or 停靠(docked) 在panel的四個邊上(left, top, right, button).
  2. 在第二步,我們定義了toolbar在哪停靠(docked). 在這裏,它的值爲top. 如果dock屬性沒有定義,默認爲top.

docked items通常爲toolbars, 但我們也可以定義其它組件,比如grids, panels, 和forms. 在toolbar屬性中的items數組中,默認的組件爲button. 這也是爲什麼我們沒有明確設置xtype的原因。

我們也可以添加其它的組件到toolbar, 比如textfield, combo box, 和 radiobutton

接下來,我們添加更多帶圖標的按紐

items:[
    {text:'New', iconCls:'addicon-16'},
    {text:'Edit', iconCls:'editicon-16'},
    {text:'Remove', iconCls:'deleteicon-16'},
    {text:'Export', iconCls:'export-16'},
    {text:'Print', iconCls:'print-16'},
    {text:'Help', iconCls:'help-16'}
]

css

.addicon-16{ background:transparent url('../images/add_16x16.png')
center 0 no-repeat !important; }
.deleteicon-16{ background:transparent url('../images/delete.png')
center 0 no-repeat !important; }
.editicon-16{ background:transparent url('../images/pencil.png')
center 0 no-repeat !important; }
.help-16{ background:transparent url('../images/help.png') center 0
no-repeat !important; }
.print-16{ background:transparent url('../images/printer.png') center
0 no-repeat !important; }
.export-16{ background:transparent url('../images/page_go.png') center
0 no-repeat !important; }

這裏寫圖片描述

Toolbar button groups

我們可以使用Ext.container.ButtonGroup類我們可以toolbar中的buttons進行分組。Ext.container.ButtonGroup是Ext.panel.Panel的一個子類。


var myPanel = Ext.create('Ext.panel.Panel',{
    title:'My first toolbar...',
    width:600,
    height:200,
    dockedItems:[{ //Step 1
        xtype : 'toolbar',
        dock: 'top', //Step 2
        items:[
            { xtype:'buttongroup',
                title:'Actions',
                items:[
                    {text: 'New', iconCls: 'addicon-16'},
                    {text: 'Edit', iconCls: 'editicon-16'},
                    {text: 'Remove', iconCls: 'deleteicon-16'}
                ]
            },{
                xtype: 'buttongroup',
                title: 'Print / Export & Help',
                items:[
                    {text: 'Export', iconCls: 'export-16'},
                    {text: 'Print', iconCls: 'print-16'},
                    {text: 'Help', iconCls: 'help-16'}
                ]
            }
        ]
    }],
    renderTo:Ext.getBody()
});

我們在這裏添加了兩個按鈕組,而不是直接將按鈕添加到toolbar, 如下所示

這裏寫圖片描述

默認情況下, buttongroup以水平排列按鈕(每個組有3列). 我們可以通過columns屬性改變它的列的大小

var myPanel = Ext.create('Ext.panel.Panel',{
    title:'My first toolbar...',
    width:600,
    height:200,
    dockedItems:[{ //Step 1
        xtype : 'toolbar',
        dock: 'top', //Step 2
        items:[
            { xtype:'buttongroup',
                title:'Actions',
                columns:2,
                items:[
                    {text:'New', iconCls:'addicon-32', scale:'large',
                        rowspan:2, iconAlign:'top' },
                    {text:'Edit', iconCls:'editicon-16'},
                    {text:'Remove', iconCls:'deleteicon-16'}
                ]
            },{
                xtype:'buttongroup', title:'Print / Export & Help',
                defaults:{scale:'large', iconAlign:'top'},
                items:[
                    {text:'Export', iconCls:'export-32'},
                    {text:'Print', iconCls:'print-32'}
                ]
            },{
                xtype:'buttongroup', title:'Help',
                items:[
                    {text:'Help', iconCls:'help-32', scale:'large',
                        iconAlign:'bottom' }
                ]
            }
        ]
    }],
    renderTo:Ext.getBody()
});

在上面的代碼中,我們設置了columns屬性爲2。這意味着在這個組中的按鈕被組織成兩列。在這裏有一個非常重要的是新按鈕的rowspan屬性。它的值爲2,這表示新按鈕使用兩行

這裏寫圖片描述

The breadcrumb bar

Ext JS 5新添加了breadcrumb bar. 它用於顯示一個分展的數據 TreeStore.


Ext.define('Myapp.sample.store.mainMenu', {
    extend: 'Ext.data.TreeStore',
    root: {
        text: 'My app',
        expanded: true,
        children: [{
            text: 'Modules',
            expanded: true,
            children: [
                {leaf: true, text: 'Employees'},
                {leaf: true, text: 'Customers'},
                {leaf: true, text: 'Products'}
            ]
        },{
            text: 'Market',
            expanded: true,
            children: [
                {leaf: true, text: 'Sales'},
                {leaf: true, text: 'Budgets'},
                {leaf: true, text: 'SEO'},
                {leaf: true, text: 'Statistics'}
            ]
        },{
            text: 'Support',
            iconCls:'help-16',
            children: [
                {leaf: true, text: 'Submit a ticket'},
                {leaf: true, text: 'Forum'},
                {leaf: true, text: 'Visit our web site'}
            ]
        },
            {leaf: true, text: 'Reports'},
            {leaf: true, text: 'Charts'}
        ]
    }
});
  • 新的Myapp.sample.store.mainMenu擴展於Ext.data.TreeStore類
  • store類中的root屬性爲TreeStore將要包含初始化的node/data model以及它的子節點/data model, 它們可以爲node數組,也可以是data models.

你會注意到, 在root屬性中的數據的結構類似於樹的結構。它將被breadcrumb bar解析,用來創建按鈕,menus, submenus。

var myMenuStore = Ext.create('Myapp.sample.store.mainMenu',{});
var myPanel = Ext.create('Ext.panel.Panel',{
    title:'My first breadcrumb bar...',
    width:600,
    height:200,
    dockedItems:[{ //Step 2
        xtype : 'breadcrumb',
        dock: 'top',
        store: myMenuStore,
        showIcons: true,
        selection: myMenuStore.getRoot().childNodes[2].childNodes[0]
    }],
    renderTo:Ext.getBody()
});

第一步,創建一個Myapp.sample.store.mainMenu的實例, 然後我們接着創建一個myPanel容器。

類似於使用toolbar, 現在我們設置xtype爲breadcrumb. 它有以下的屬性

  • store: myMenuStore屬性用來指示breadcrumb從哪裏獲取數據,然後創建相應的組件(buttons, menus)
  • showIcons: true屬性將用來控制是否在buttons中顯示圖標
  • selection屬性用來設置初步選定的node/data model. 我們可以使用root,將它設置爲store中的第一個元素,或者像我們一樣,設置爲myMenuStore.getRoot().childNodes[2].childNodes[0], 它表示”Submit a ticket” 節點

這裏寫圖片描述

Handling selections in the breadcrumb bar

我們現在已經創建完了breadcrumb, 但我們需要在它的選擇做相應的事件監聽。它有一個selectionchange事件,它每次在我們點擊按鈕或者菜單項時觸發

dockedItems:[{
    xtype : 'breadcrumb',
    dock: 'top',
    store: myMenuStore,
    showIcons: true,
    selection: myMenuStore.getRoot().childNodes[2].childNodes[0],
    listeners:{
        'selectionchange':{
            fn:function(mybreadcrumb, node, eOpts){
                var panel = mybreadcrumb.up('panel');
                panel.update( 'This is the zone for:<b>' + node.data.text +
                        '</b>' );
            },
            delay:200
        }
    }
}],

處理函數將按受三個參數,第一個是mybreadcrumb實例,第二個是選擇的節點(data model), 第三個參數是一個可選的對像,它將傳遞給Ext.util.Obserable.addListener監聽器。

The main menu for our application

在接下來,我們將創建一個應用程序的主菜單。如下圖所示

這裏寫圖片描述

如截圖所示,我們創建了一個toolbar,停靠在top位置。別一個toolbar停靠在bottom位置。 第一個toolbar將包含兩個按鈕(每一個按鈕有自己的菜單)以及一個用來顯示用戶名的text item, Ext.toolbar.TextItem. 第二個toolbar有一個text item和一個help button.

爲了練習,我們需要將整個組件佔居整個瀏覽器。目前爲此,我們都是使用panel作爲容器,但現在,我們將使用Viewport.

Ext.container.Viewport組件將佔用所有可用的空間,並且監聽resize事件。


Ext.define('MyApp.view.Viewport',{
    extend: 'Ext.container.Viewport',
    layout: 'fit',
    initComponent: function(){
        var me = this;
        me.items = [{
            xtype: 'panel',
        }];
        me.callParent();
    }
});

Viewport類繼承於container組件,所以我們也可以使用layout進行佈局,在這裏,我們使用的是fit layout. 因爲我們想要將viewport的子元素最大化爲瀏覽器。

我們之前提到過,如果我們想要依靠一個組件到四個邊中的一邊,我們需要使用一個panel. 下面的代碼將添加一個空的panel到Viewport.

me.items = [{
    xtype: 'panel',
}];

然後爲這個空 panel,指定docked items

dockedItems: [{
    xtype: 'toolbar', docked:'top',
    items: [{
        text: 'Home', iconCls: 'home-16',
        menu:[
            {text: 'Categories', iconCls: 'categories-16'},
            {text: 'Products', iconCls: 'products-16'},
            {text: 'Clients', iconCls: 'clients-16' },
            {text: 'Invoices', iconCls: 'invoices-16'}
        ]
    },{
        text: 'Help', iconCls: 'help-16',
        menu: {
            xtype: 'menu',
            items: [
                {xtype: 'menuitem', text: 'Submit a support ticket'},
                {xtype: 'menuitem', text: 'Forum'},
                {xtype: 'menuitem', text: 'About...'}
            ]
        }
    },
        {xtype: 'tbfill'},
        {xtype: 'tbtext', text: 'User: Brett Fravre'}
    ]
}]

在上面的toolbar中,我們添加了兩個新的元素

  • tbfill or Ext.toolbar.Fill: 它是一個佔位符元素,會強制將接下來的元素渲染到最右側
  • tbtext or Ext.toolbar.TextItem: 渲染一個文本或者html元素

接下來,創建這個Viewport實例

Ext.onReady(function(){
    Ext.create("MyApp.view.Viewport");
});

在Viewport中我們不需要renderTo屬性。因爲它會自動獲取document body.

這裏寫圖片描述

接下來,我們創建bottom toolbar

dockedItems : [{
    xtype : 'toolbar', docked:'top',
//your code here…
},
    {
        xtype : 'toolbar', dock:'bottom',
        items : [
            {xtype: 'tbtext', text: '<b>Status :</b>Connected'},
            {xtype: 'tbfill' },
            {text:'', iconCls: 'help-16'}
        ]
    }]

Example

自定義一個button基礎類

/**
 * Created by robin on 2016/9/6.
 * 自定義Button基礎類
 * btnStyle的值可以爲blue, grey, green, red, orange,用於設置按紐的顏色, 默認爲default
 * htmlEncode 是否對按鈕的文字進行html編碼,默認爲true
 * @cfg {number} indent:  setFormItemIndent使用,調整button的縮進
 */
Ext.define('Cms.ux.Button', {
    extend: 'Ext.button.Button',
    alias: 'widget.cms_button',
    btnStyle: "default", //custom configuration, 指定按鈕的樣式,區別於cls, 統一添加樣式
    htmlEncode: true, //custom configuration  調用Ext.util.Format.htmlEncode格式化按鈕文字
    requires: [
        "Cms.ux.Utils",
    ],
    constructor: function (config) {
        this.callParent(arguments); //參數必須爲類數組 [config]
        this.updateButtonStyle(config);
        //如果button類型爲menu
        if (this.menu) {
            this.menu.cls = this.menu.cls ? this.menu.cls + " syno-ux-button-menu" : "syno-us-button-menu";
            this.menu.shadow = false;
        }

    },
    updateButtonStyle: function (config) {
        this.addCls("cms-ux-button");
        switch (this.btnStyle) {
            case "blue":
                this.addCls("cms-ux-button-blue");
                this.minWidth = 80; //minWidth is configuration option
                break;
            case "grey":
                this.addCls("cms-ux-button-grey");
                this.minWidth = 80; //minWidth is configuration option
                break
            case "green":
                this.addCls("cms-ux-button-green");
                this.minWidth = 80; //minWidth is configuration option
                break;
            case "red":
                this.addCls("cms-ux-button-red");
                this.minWidth = 80; //minWidth is configuration option
                break;
            case "orange":
                this.addCls("cms-ux-button-orange");
                this.minWidth = 80; //minWidth is configuration option
                break;
            default:
                this.addCls("cms-ux-button-default");
        }
    },
    applyText: function (t) {
        console.log("text")
        if (this.htmlEncode) {
            t = Ext.util.Format.htmlEncode(t);
        }

        return t;
    },
    /**
     * 此方法主要在button渲染後調用, 整個方法的實現,可以查看Ext.button.Button.setText源文件
     * version 6 源代碼中沒有此方法, 它是config中的屬性,所有自動生成setText方法
     * version 3 源代碼中有這個方法
     *
     * @param {string}
     */
    /*
     setText: function (t) {
     this.text = t;
     //如果在渲染後調用onRender,afterRender
     if (this.el) {

     if (this.htmlEncode) {
     //this.btnEl返回可點擊的部分(最裏面的元素),而不是整個button,然後更新文字
     //this.btnEl沒有出現在Ext js 6的文檔中,但是在源代碼裏,同時在Ext js 3.4.0也存在
     //this.btnEl是一個Ext.Element元素,所以可以調用update更新它的內容
     this.btnEl.update(Ext.util.Format.htmlEncode(t))
     } else {
     this.btnEl.update(t || '&#160;');
     }
     //setButtonClass是一個內部方法,所以在文檔中沒有這個方法, 需要查看源文件
     this.setButtonClass();
     }
     //version 6 沒有此方法
     this.doAutoWidth();
     this.fireEvent("textchanged", this, t)
     }*/

    onRender: function () {
        this.callParent(arguments);
        Cms.ux.Utils.setFormItemIndent(this);
    },
    getAriaEl: function () {
        return this.btnEl;
    }

});
/**
 * Created by robin on 2016/9/7.
 * @class Cms.ux.Utils
 * 參考Ext.util.Format寫法
 */
Ext.define('Cms.ux.Utils', function () {
    var me;
    return {
        singleton: true,
        constructor: function () {
            me = this;
        },
        /**
         *
         * @param element 需要縮進的元素 1級縮進30, 2級縮進30
         */
        setFormItemIndent: function (el) {
            var indent = el.indent || 0;
            var m = indent * 30;
            /* 如果元素爲textfield, 則它有label屬性, 獲取到labelEl元素, Ext.dom.Element, version 3 爲label屬性*/
            if (el.labelEl && !el.hideLabel) {
                //d.ownerCt 獲取這個組件的容器, 如Ext.form.field.Text labelAlign
                if (el.ownerCt && "top" === el.ownerCt.labelAlign) {
                    el.label.setStyle({
                        "margin-left": m + "px"
                    })
                } else {
                    //labelWidth是一個配置項, 整個w等於indent + labelWidth
                    var w = el.labelWidth || d.ownerCt.labelWidth || 180;

                    d.label.setStyle({
                        "margin-left": m + "px",
                        width: w - m + "px"
                    })
                }

            } else {
                if (el.wrap) {
                    el.wrap.setStyle({
                        "margin-left": m + "px"
                    })
                } else {
                    el.getEl().setStyle({
                        "margin-left": m + "px"
                    })
                }
            }
            //設置按鈕的等級 
            if (el instanceof Cms.ux.Button) {
                //設置按鈕最內層(可點擊)元素的aria-level屬性, btnEl可以查看源代碼,文檔中沒有
                el.btnEl.set({
                    "aria-level": indent + 1
                });
                if (el.arrowBtnEl) {
                    el.arrowBtnEl.set({
                        'aria-level': indent + 1
                    })
                }
            } else {
                el.getEl().set({
                    "aria-level": indent + 1
                })
            }
            return el;
        }
    }
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章