sencha touch学习笔记二:编写第一个例子

时间:2023-01-27 13:46:07

Sencha Touch官网所给的例子还是很详尽的,只要把代码拷贝粘贴,稍微修改一下,就能用在自己的项目中了,或者仔细看官网给的例子,代码注释给的英文也不难,自学那些代码,完全不需要看什么视频和书籍。有学习过Extjs那就更好了,因为这两个产品都是Sencha公司的,代码风格几乎一样。

先看看Sencha CMD生成的项目中都有些什么。

sencha touch学习笔记二:编写第一个例子

.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技术的异步请求。

sencha touch学习笔记二:编写第一个例子

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

sencha touch学习笔记二:编写第一个例子

前者是CMD编译产生的,后者是自己编写项目用的。

进入bootstrap.json里面

sencha touch学习笔记二:编写第一个例子

Sencha需要引用的文件从这引用。主入口的jscss文件都提示出来了。进入app.js里面

sencha touch学习笔记二:编写第一个例子

这里面居然也没有界面展现的内容,直到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>

sencha touch学习笔记二:编写第一个例子


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


sencha touch学习笔记二:编写第一个例子

先不管其他的东西,app.js文件是我们的入口,按照MVC模式来编写的,你仔细一看,还是能看到模型,控制,视图分开的风格。Main.js是我们的视图展示层,只不过需要单独引用而已。要学习Sencha,对app.js这个文件进行修改,我们就可以简单地学Sencha Touch了。

 

下面我们来学习并改一下demo中的源代码,以list为例子。

在手机上的表现是这样的:

sencha touch学习笔记二:编写第一个例子

源代码在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/icon@72.png',
        114: 'resources/icons/icon@2x.png',
        144: 'resources/icons/icon@144.png'
    },

    //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文件内容。不熟悉的话一个个敲,培养一下敲码的感觉。

sencha touch学习笔记二:编写第一个例子

虽然是照抄右边的,可是边敲边加深了理解。这里推荐用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/icon@72.png',
        114: 'resources/icons/icon@2x.png',
        144: 'resources/icons/icon@144.png'
    },

    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>


在电脑上显示如下:

sencha touch学习笔记二:编写第一个例子

在手机上显示如下:

sencha touch学习笔记二:编写第一个例子