Sencha Touch開發一些須要注意的地方

Sencha Touch開發一些須要注意的問題

現在Sencha Touch已經升級到2.4了,功能更增強大,性能也有所提高。
但因爲一些功能的改進,文檔並無及時更新,致使開發時會遇到一些困難。
結合我使用的經驗總結一些須要注意的地方,但願能幫助你們。

-------------------
Sencha Touch的開發流程

下載SDK,安裝Sencha Cmd。

建立項目: css

sencha generate app MyApp ../test
打包項目(壓縮,便於部署)
sencha app build
由cmd生成的項目會自動加載類庫文件,文件太多,致使等待時間過長,
能夠直接引入resources/css/sencha.css和sencha_touch_all.js來提升速度,
但打包時須要還原,不然會出錯

根目錄下的app.js是程序的入口文件,代碼以下所示:
Ext.application({
    name: 'MyApp', //The name is used to create a single global namespace for your entire app

    requires: [
        'Ext.MessageBox',
        'Ext.navigation.View',
        'Ext.dataview.List',
        'Ext.plugin.PullRefresh',
        'Ext.plugin.ListPaging'
    ],

    controllers:[
        'Main'
    ],

    views: [
        'Main',
        'ArticleList'
    ],

    models:[
        'MyApp.model.Article'
    ],

    stores:[
        'MyApp.store.Articles'
    ],

    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/Icon@2x.png',
        '144': 'resources/icons/Icon~ipad@2x.png'
    },

    isIconPrecomposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    launch: function() {
        // Destroy the #appLoadingIndicator element
        Ext.fly('appLoadingIndicator').destroy();

        // Initialize the main view
        Ext.Viewport.add(Ext.create('MyApp.view.Main'));
    },

    onUpdated: function() {
        Ext.Msg.confirm(
            "Application Update",
            "This application has just successfully been updated to the latest version. Reload now?",
            function(buttonId) {
                if (buttonId === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

用到的組件都須要在requires中引入,不然JS調試器中會有警告,
Sencha Touch採用MVC結構,全部controller、model、store、view文件須要在這裏引入.
實際文件存放在app文件夾下的相應目錄
-------------------------------------
自定義組件除了extend屬性,其餘屬性須要寫在config下:
Ext.define("MyApp.model.Article", {
    extend: "Ext.data.Model",
    config: {
        fields: [
            {name: "title", type: "string"},
            {name: "content",  type: "string"},
            {name: "add_time", type: "string"}
        ]
    }
});

Ext.define('MyApp.store.Articles',{
    extend:'Ext.data.Store',
    config:{
        model: "MyApp.model.Article",
        proxy: {
            type: "ajax",
            url : listUrl,
            reader: {
                type: "json",
                rootProperty: "root"
            }
        },
        autoLoad: true,
        pageSize:10,
        listeners:{
            'beforeload':function(store){
                //console.log('start');
                if(store.getAllCount()==0){
                    showMask();
                }
            },
            'load':function(){
                hideMask();
            }
        }
    }
});
----------------------------------
card佈局能夠配置頁面的切換動畫
Ext.create('Ext.Panel',{
layout:{
    type:'card',
    animation:'fade'
},
items:[
    {
    .....
    },
    {
    .....
    }
 ]
});

----------------------------------

Ext.dom.Element,同Ext.Element,是Sencha Touch封裝的dom對象,
是對普通dom的進一步封裝,給dom對象添加了一些新方法
// 根據id獲取元素,返回Ext.Element類型
var el = Ext.get("my-div");
// 根據HTMLElement獲取元素,返回Ext.Element類型
var el = Ext.get(myDivElement);

//HTMLElement是普通的dom對象

//Ext.Element 獲取全部img 返回數組(HTMLElement)
el.query('img');

//Ext.Element 獲取第一個img 返回單個對象(HTMLElement)
el.down('img',true);

//返回單個對象(Ext.dom.Element)
el.down('img');

//Ext.dom.Element修改樣式
el.applyStyles({
    color:'red'
});

//普通HTMLElement修改樣式
el.style.width = '100%';

-----------------------------------
//建立loading
Ext.Viewport.setMasked({
    xtype:'loadmask',
    message:'請稍後...'
});

//關閉loading 爲何不是unMask?很奇怪
Ext.Viewport.unmask();

//也可使用
Ext.Viewport.setMasked(false);
-----------------------------------
文檔中方法帶綠色右箭頭表示CHAINABLE,支持相似jQuery的鏈式語法
------------------------
painted事件
Fires whenever this Element actually becomes visible (painted) on the screen
該事件發生在dom加載完成時
----------------------------------
在使用佈局時,必定要注意,若是父元素不配置layout屬性(默認將爲auto佈局)
子元素必定要有高度,不然可能不會顯示出來,即高度爲0

card佈局示例:
var panel = Ext.create('Ext.Panel', {
    layout: 'card',
    items: [
        {
            html: "First Item"
        },
        {
            html: "Second Item"
        },
        {
            html: "Third Item"
        },
        {
            html: "Fourth Item"
        }
    ]
});

panel.setActiveItem(1);

每種佈局方式都支持docked(停靠)屬性:
靈活使用docked屬性,能夠很方便建立複雜的佈局
Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'hbox',
    items: [
        {
            docked: 'top', //能夠是top bottom right left
            xtype: 'panel',
            height: 20,
            html: 'This is docked to the top'
        },
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});

pack和align是佈局的兩個輔助定義項,pack表明了當前佈局維度的特性,align則相反
例如對hbox佈局,pack的定義表示水平方向的特性,而align表示垂直方向的特性:

layout: {
    type: 'hbox',
    align: 'start', //垂直方向停靠起始位置
    pack: 'start' //水平方向停靠起始方向,效果等同左對齊
},

align和pack可能的值:
start   
center 居中對齊
end
justify 兩端對齊(自適應父元素的寬度或高度)

能夠理解爲word排版中的四種對齊方式:
左對齊
右對齊
居中對齊
兩端對齊 

獲取容器的佈局
var layout = container.getLayout();
-----------------------------------------

對於滾動屬性的說明。
每一個容器均可以經過配置scrollable:true來實現滾動,
但要注意,對於子元素有滾動的,父元素不能有滾動,不然可能會出現滾動條衝突的問題

-----------------------------

使用控制器能夠是代碼變得乾淨和可讀性強,下面的例子展現了controller的使用:

Ext.define('MyApp.controller.Sessions', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            loginForm: 'formpanel' //組件查詢 使用xtype 
        },
        control: {
            'formpanel button': { //也可使用相似於css選擇器的查詢方式
                tap: 'doLogin' //該方法在下面定義
            }
        }
    },

    doLogin: function() {
        var form   = this.getLoginForm(), //根據refs中的loginForm自動生成getLoginForm方法

            values = form.getValues();

        MyApp.authenticate(values);
    }
});

-----------------------------------

組件查詢(ComponentQuery),使用組件查詢能夠像CSS選擇器同樣
獲取應用中的組件,下面經過一些例子來展現這一強大功能。
//獲取指定屬性的panel
Ext.ComponentQuery.query('panel[cls=my-cls]')

//模糊查詢
Ext.ComponentQuery.query('panel[cls~=my-cls]')
//匹配結果
Ext.create('My.Panel', {
    cls : 'foo-cls my-cls bar-cls'
});

//根據id查詢
Ext.ComponentQuery.query('#myCt panel');

//查詢孩子節點
var directChildPanel = Ext.ComponentQuery.query('#myCt > panel');

//查詢多個組件
Ext.ComponentQuery.query('gridpanel, treepanel');

//獲取禁用的元素
var disabledFields = myFormPanel.query("{isDisabled()}");

//值得注意的是,相似於isDisabled這樣的方法還有一些,只要是返回布爾類型的,均可以做爲
//查詢參數,另外,query方法不僅是能夠用於Ext.ComponentQuery,對於每一個容器組件均可以使用,上面的
//查詢將會在myFormPanel的子元素中進行,而Ext.ComponentQuery.query的查詢範圍是全局
--------------------------------

//利用profile能夠爲不一樣的設備建立不一樣的界面,而共享相同的model和store
//現階段咱們不須要實現這樣的功能,因此不作研究

//一些組件的初始化方法的執行順序:
Controller#init functions called
Profile#launch function called
Application#launch function called
Controller#launch functions called
//能夠利用該順序來合理執行一些初始化邏輯
相關文章
相關標籤/搜索