sencha touch學習筆記二:編寫第一個例子

Sencha Touch官網所給的例子還是很詳盡的,只要把代碼拷貝粘貼,稍微修改一下,就能用在自己的項目中了,或者仔細看官網給的例子,代碼註釋給的英文也不難,自學那些代碼,完全不需要看什麼視頻和書籍。有學習過Extjs那就更好了,因爲這兩個產品都是Sencha公司的,代碼風格幾乎一樣。

先看看Sencha CMD生成的項目中都有些什麼。

.sencha : 自動生成的配置文件,不知是玩意,先不管。

app : 裏面放着空的模型(model),視圖(view)和存儲(store)文件夾,再等着你編輯文件放進去呢!爲什麼會有這些文件夾,因爲Sencha Touch是以MVC模式來進行開發的。

build : 編譯後的文件存放在這個文件夾裏面,我們編寫完Sencha項目,可以編譯成原生的Android項目或者IOS項目的,用Sencha CMD可以,用phonegap更好,這是後話了。

packages :包文件夾,放什麼包的吧,我也不知道。

resources:這個比較重要,放css和圖片資源的。

touchsdk):Sencha Touch SDK的拷貝,不要修改這個文件夾裏面的東西。

剩下的都不是文件夾了

app.js javascript入口

app.json 配置文件,用來創建你的應用的縮小版本

index.html 你的應用的HTML文件

packager.json 配置文件,用來打包成IOSAndroid應用

bootstrap.js 流行的bootstrap框架應用文件

 

當我們訪問這個項目時,打開的是根目錄下的index.html文件,所以打開這個文件看一下里面的源代碼:

<span style="font-size:24px;"><!DOCTYPE HTML>
<html manifest="" lang="en-US">
<head>
    <meta charset="UTF-8">
    <title>first</title>
    <style type="text/css">
         /**
         * Example of an initial loading indicator.
         * It is recommended to keep this as minimal as possible to provide instant feedback
         * while other resources are still being loaded for the first time
         */
        html, body {
            height: 100%;
            background-color: #1985D0
        }

        #appLoadingIndicator {
            position: absolute;
            top: 50%;
            margin-top: -15px;
            text-align: center;
            width: 100%;
            height: 30px;
            -webkit-animation-name: appLoadingIndicator;
            -webkit-animation-duration: 0.5s;
            -webkit-animation-iteration-count: infinite;
            -webkit-animation-direction: linear;
        }

        #appLoadingIndicator > * {
            background-color: #FFFFFF;
            display: inline-block;
            height: 30px;
            -webkit-border-radius: 15px;
            margin: 0 5px;
            width: 30px;
            opacity: 0.8;
        }

        @-webkit-keyframes appLoadingIndicator{
            0% {
                opacity: 0.8
            }
            50% {
                opacity: 0
            }
            100% {
                opacity: 0.8
            }
        }
    </style>
    <!-- The line below must be kept intact for Sencha Command to build your application -->
    <script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script>
</head>
<body>
    <div id="appLoadingIndicator">
        <div></div>
        <div></div>
        <div></div>
    </div>
</body>
</html></span>

非常簡單,只有css樣式代碼和一個引用的js文件,這樣就能豐富地表達我們的例子 ?

按住“ctrl”鍵,點擊development.js。跳轉到裏面看看。這個文件居然在.sencha文件夾裏面的。Javascript對於我來說不是擅長的語言,所以看這些代碼開始一頭霧水。源代碼下面有很多設備的名稱,看來是匹配這些設備,讓體驗更佳的。可是我們所看到的頁面的那些文字在這裏面一點都沒有涉及,難道還有引用文件,仔細一看,不小心還看不到呢,最後看到Ajax技術的異步請求。

而在touch\microloader\development.js中,指向的卻是

前者是CMD編譯產生的,後者是自己編寫項目用的。

進入bootstrap.json裏面

Sencha需要引用的文件從這引用。主入口的jscss文件都提示出來了。進入app.js裏面

這裏面居然也沒有界面展現的內容,直到Ext.Viewport.add(Ext.create('first.view.Main'));這一行。點擊進入Main.js文件,這個文件在app文件夾裏面的視圖層view文件夾裏面。打開

<span style="font-size:24px;">Ext.define('first.view.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'main',
    requires: [
        'Ext.TitleBar',
        'Ext.Video'
    ],
    config: {
        tabBarPosition: 'bottom',

        items: [
            {
                title: 'Welcome',
                iconCls: 'home',

                styleHtmlContent: true,
                scrollable: true,

                items: {
                    docked: 'top',
                    xtype: 'titlebar',
                    title: 'Welcome to Sencha Touch 2'
                },

                html: [
                    "You've just generated a new Sencha Touch 2 project. What you're looking at right now is the ",
                    "contents of <a target='_blank' href=\"app/view/Main.js\">app/view/Main.js</a> - edit that file ",
                    "and refresh to change what's rendered here."
                ].join("")
            },
            {
                title: 'Get Started',
                iconCls: 'action',

                items: [
                    {
                        docked: 'top',
                        xtype: 'titlebar',
                        title: 'Getting Started'
                    },
                    {
                        xtype: 'video',
                        url: 'http://av.vimeo.com/64284/137/87347327.mp4?token=1330978144_f9b698fea38cd408d52a2393240c896c',
                        posterUrl: 'http://b.vimeocdn.com/ts/261/062/261062119_640.jpg'
                    }
                ]
            }
        ]
    }
});</span>

到此一切都明朗了!

我們打開index頁面,index加載的development.js,適配我們的設備,然後頁面展現進度的過程同時,異步請求bootstrap.json中的js文件和CSS文件,加載Senchajs文件和樣式文件,加載進根目錄下的app.js文件,觸發first.view.Main,加載Main.js文件,從而真正展現Sencha的頁面出來,Main.js裏面的內容和我們看到的文字是一樣的,所以稍微修改一些內容,就會展現不同的內容出來。

<span style="font-size:24px;">Ext.define('first.view.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'main',
    requires: [
        'Ext.TitleBar',
        'Ext.Video'
    ],
    config: {
        tabBarPosition: 'bottom',

        items: [
            {
                title: '歡迎',
                iconCls: 'home',

                styleHtmlContent: true,
                scrollable: true,

                items: {
                    docked: 'top',
                    xtype: 'titlebar',
                    title: '歡迎來到 Sencha Touch'
                },

                html: [
                    "這是個Sencha Touch頁面"
                ].join("")
            },
            {
                title: '視頻',
                iconCls: 'action',

                items: [
                    {
                        docked: 'top',
                        xtype: 'titlebar',
                        title: '請看視頻'
                    },
                    {
                        xtype: 'video',
                        url: 'http://av.vimeo.com/64284/137/87347327.mp4?token=1330978144_f9b698fea38cd408d52a2393240c896c',
                        posterUrl: 'http://b.vimeocdn.com/ts/261/062/261062119_640.jpg'
                    }
                ]
            }
        ]
    }
});</span>


=================================================================================


先不管其他的東西,app.js文件是我們的入口,按照MVC模式來編寫的,你仔細一看,還是能看到模型,控制,視圖分開的風格。Main.js是我們的視圖展示層,只不過需要單獨引用而已。要學習Sencha,對app.js這個文件進行修改,我們就可以簡單地學Sencha Touch了。

 

下面我們來學習並改一下demo中的源代碼,以list爲例子。

在手機上的表現是這樣的:

源代碼在touch-2.3.0\examples\list中。其中加入了一些個人理解的中文註釋,英語還可以的可看官方的註釋,寫得很簡單明白。

<span style="font-size:24px;">//<debug>
Ext.Loader.setPath({
    'Ext': '../../src'
});
//</debug>

/**
 * This simple example shows the ability of the Ext.List component.
 *
 * In this example, it uses a grouped store to show group headers in the list. It also
 * includes an indicator so you can quickly swipe through each of the groups. On top of that
 * it has a disclosure button so you can disclose more information for a list item.
 */

//define the application
//定義程序,入口
Ext.application({
    //define the startupscreens for tablet and phone, as well as the icon
    //根據移動設備的分辨率來選擇不同的圖片
    startupImage: {
        '320x460': 'resources/startup/Default.jpg', // Non-retina iPhone, iPod touch, and all Android devices
        '640x920': 'resources/startup/640x920.png', // Retina iPhone and iPod touch
        '640x1096': 'resources/startup/640x1096.png', // iPhone 5 and iPod touch (fifth generation)
        '768x1004': 'resources/startup/768x1004.png', //  Non-retina iPad (first and second generation) in portrait orientation
        '748x1024': 'resources/startup/748x1024.png', //  Non-retina iPad (first and second generation) in landscape orientation
        '1536x2008': 'resources/startup/1536x2008.png', // : Retina iPad (third generation) in portrait orientation
        '1496x2048': 'resources/startup/1496x2048.png' // : Retina iPad (third generation) in landscape orientation
    },

    isIconPrecomposed: false,
    icon: {
        57: 'resources/icons/icon.png',
        72: 'resources/icons/[email protected]',
        114: 'resources/icons/[email protected]',
        144: 'resources/icons/[email protected]'
    },

    //require any components/classes what we will use in our example
    //需要用到的組件
    requires: [
        'Ext.MessageBox',
        'Ext.data.Store',
        'Ext.List',
        'Ext.plugin.PullRefresh'
    ],

    /**
     * The launch method is called when the browser is ready, and the application can launch.
     *
     * Inside our launch method we create the list and show in in the viewport. We get the lists configuration
     * using the getListConfiguration method which we defined below.
     *
     * If the user is not on a phone, we wrap the list inside a panel which is centered on the page.
     */
    //觸發,英文上說得很淺顯易懂
    launch: function() {
        //get the configuration for the list
        //list界面對象
        var listConfiguration = this.getListConfiguration();

        //if the device is not a phone, we want to create a centered panel and put the list
        //into that
        //phone與其他設備是有區別的,源於iphone的分辨率比較特殊
        if (!Ext.os.is.Phone) {
            //use Ext.Viewport.add to add a new component into the viewport
            Ext.Viewport.add({
                //give it an xtype of panel
                xtype: 'panel',

                //give it a fixed witdh and height
                width: 350,
                height: 370,

                //make it centered
                centered: true,

                //make the component modal so there is a mask around the panel
                modal: true,

                //set hideOnMaskTap to false so the panel does not hide when you tap on the mask
                hideOnMaskTap: false,

                //give it a layout of fit so the list stretches to the size of this panel
                layout: 'fit',

                //insert the listConfiguration as an item into this panel
                items: [listConfiguration]
            });
        } else {
            //if we are a phone, simply add the list as an item to the viewport
            Ext.Viewport.add(listConfiguration);
        }
    },

    /**
     * Returns a configuration object to be used when adding the list to the viewport.
     */
        //界面對象,返回到面板裏面填充,從而有內容展現
    getListConfiguration: function() {
        //create a store instance
        //存儲器
        var store = Ext.create('Ext.data.Store', {
            //give the store some fields
            fields: ['firstName', 'lastName'],

            //filter the data using the firstName field
            sorters: 'firstName',

            //autoload the data from the server
            autoLoad: true,

            //setup the grouping functionality to group by the first letter of the firstName field
            grouper: {
                groupFn: function(record) {
                    return record.get('firstName')[0];
                }
            },

            //setup the proxy for the store to use an ajax proxy and give it a url to load
            //the local contacts.json file
            //異步加載數據,這裏可以改編成與後臺的controller交互,controller從數據庫中獲取數據
            proxy: {
                type: 'ajax',
                url: 'contacts.json'
            }
        });

        return {
            //give it an xtype of list for the list component
            xtype: 'list',

            id: 'list',

//            scrollable: {
//                indicators: false
//            },

            //set the itemtpl to show the fields for the store
            //從store裏面提取的數據怎麼展現
            itemTpl: '{firstName} {lastName}',

            //enable disclosure icons
            //disclosure: true,

            //group the list
            //分組
            grouped: true,

            //enable the indexBar
            indexBar: true,

            infinite: true,

            useSimpleItems: true,

            variableHeights: true,

            striped: true,
            //ui主題
            ui: 'round',

            //set the function when a user taps on a disclsoure icon
            // onItemDisclosure: function(record, item, index, e) {
            //     //show a messagebox alert which shows the persons firstName
            //     e.stopEvent();
            //     Ext.Msg.alert('Disclose', 'Disclose more info for ' + record.get('firstName'));
            // },

            //bind the store to this list
            store: store
        };
    }
});</span>


看一下存儲器store請求的異步數據,這是一個靜態數據contacts.json文件,這裏我們當然可以用各種後臺技術把關係型數據庫轉換爲json數據傳到這裏來,或者一些key-value數據庫直接傳過來,也可以經過過濾。

<span style="font-size:24px;">[
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Ape", "lastName": "Evilias" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Ape", "lastName": "Evilias" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Ape", "lastName": "Evilias" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Ape", "lastName": "Evilias" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Tommy", "lastName": "Maintz" },
     { "firstName": "Ed", "lastName": "Spencer" },
     { "firstName": "Jamie", "lastName": "Avins" },
     { "firstName": "Aaron", "lastName": "Conran" },
     { "firstName": "Dave", "lastName": "Kaneda" },
     { "firstName": "Michael", "lastName": "Mullany" },
     { "firstName": "Abraham", "lastName": "Elias" },
     { "firstName": "Jay", "lastName": "Robinson" },
     { "firstName": "Zed", "lastName": "Zacharias "}
]</span>

看到這裏,事情就變得很簡單了,按照這個例子稍微改一下就可以用了,至於各個參數的含義,還有其他的各種參數,要參考官網的API文檔纔可以。Sencha Touch在這一點不夠Extjs好,Extjs可以離線看整個API文檔,瀏覽速度非常快,可是Sencha Touch卻要聯網到它的官網上查看,我所在的這個地方瀏覽官網非常慢,不知是不是地區網絡的問題,反正想看一下API文檔非常困難,以後想辦法找個離線的纔好,即使低版本的也好!

 

我們改這個例子,成爲中文的通訊錄列表。

先修改contacts.json文件,這些都是靜態數據,純粹無腦機械編輯,這應該留給後臺靈活返回數據顯示出來的,不過剛入門,還是以靜態數據爲例子吧!把這個文件放到我們的項目的根目錄下。

[
     { "name": "李四", "age": 23, "address":"中山路1號" },
     { "name": "王五", "age": 26, "address":"中山路12號" },
     { "name": "王五1", "age": 34, "address":"中山路18號" },
     { "name": "王五2", "age": 55, "address":"中山路156號" },
     { "name": "王五3", "age": 34, "address":"解放路34號" },
     { "name": "王五4", "age": 12, "address":"解放路45號" },
     { "name": "王五5", "age": 89, "address":"解放路67號" },
     { "name": "王五6", "age": 45, "address":"解放路93號" },
     { "name": "趙六", "age": 67, "address":"解放路57號" },
     { "name": "王7", "age": 23, "address":"白雲路3號" },
     { "name": "張三", "age": 67, "address":"昆明路78號" },
     { "name": "趙霽", "age": 34, "address":"解放路98號" },
     { "name": "周麗", "age": 56, "address":"解放路175號" },
     { "name": "李賢", "age": 34, "address":"解放路876號" },
     { "name": "孫琦", "age": 56, "address":"解放路32號" },
     { "name": "黃連", "age": 28, "address":"解放路78號" },
     { "name": "張麗", "age": 25, "address":"解放路45號" },
     { "name": "里人", "age": 22, "address":"解放路89號" },
     { "name": "方琪", "age": 23, "address":"解放路23號" },
     { "name": "李燕", "age": 34, "address":"中山路4號" }

]

備份app.js文件,接着改app.js文件內容。不熟悉的話一個個敲,培養一下敲碼的感覺。


雖然是照抄右邊的,可是邊敲邊加深了理解。這裏推薦用intellij這個IDE,因爲不用安裝插件就可以提示Sencha Touch函數、參數等信息了,非常智能!

改的app.js如下:

<span style="font-size:24px;">Ext.application({
    startupImage: {
        '320x460': 'resources/startup/Default.jpg',
        '640x920': 'resources/startup/640x920.png',
        '640x1096': 'resources/startup/640x1096.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    isIconPrecomposed: false,
    icon: {
        57: 'resources/icons/icon.png',
        72: 'resources/icons/[email protected]',
        114: 'resources/icons/[email protected]',
        144: 'resources/icons/[email protected]'
    },

    requires: [
        'Ext.MessageBox',
        'Ext.data.Store',
        'Ext.List',
        'Ext.plugin.PullRefresh'
    ],
    launch : function() {

        var listConfiguration = this.getListConfiguration();

        if (!Ext.os.is.Phone) {
            Ext.Viewport.add({
                xtype: 'panel',
                width: 350,
                height: 370,
                centered: true,
                modal: true,
                hideOnMaskTap: false,
                layout: 'fit',
                items: [listConfiguration]
            });
        } else {
            Ext.Viewport.add(listConfiguration);
        }
    },

    getListConfiguration : function() {
        var store = Ext.create('Ext.data.Store',{
            fields:['name','age','address'],
            sorters:'name',
            autoLoad:true,
            grouper:{
                groupFn:function(record) {
                    return record.get('name')[0];
                }
            },
            proxy:{
                type:'ajax',
                url:'contacts.json'
            }
        });

        return {
            xtype:'list',
            id:'list',
            itemTpl:'{name}{age}{address}',
            grouped:true,
            indexBar:true,
            infinite:true,
            useSimpleItems:true,
            variableHeights:true,
            striped:true,
            ui:'round',
            store:store
        }
    }
});</span>


在電腦上顯示如下:


在手機上顯示如下:


發佈了57 篇原創文章 · 獲贊 13 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章