构建你第一个App

准备

本指南基于开始使用sencha touch这篇文章,这文章让你已经让你设置安装成功了Sencha Touch SDK 并且确保你的环境工作正常。如果你还没有阅读它,请在阅读本指南时阅读它。

我们要构建什么

我们将构建一个简单的移动web应用程序使用公司的移动网站。这个应用包含一个home主页, 一个联系人表单, 和一个简单的列表加载你最新的发布的博客并允许访问者通过移动设备访问。

这个简单的app代码如下:

Ext.application({
    name: 'Sencha',
 
    launch: function() {
        // The whole app UI lives in this tab panel
        Ext.Viewport.add({
            xtype: 'tabpanel',
            fullscreen: true,
            tabBarPosition: 'bottom',
 
            items: [
                // This is the home page, just some simple HTML
                {
                    title: 'Home',
                    iconCls: 'home',
                    cls: 'home',
                    html: [
                        '<img height=260 src="http://staging.sencha.com/img/sencha.png" />',
                        '<h1>Welcome to Sencha Touch</h1>',
                        "<p>Building the Getting Started app.</p>",
                        '<h2>Sencha Touch</h2>'
                    ].join("")
                },
 
                // This is the recent blogs page. It uses a tree store to load its data from blog.json.
                {
                    xtype: 'nestedlist',
                    title: 'Blog',
                    iconCls: 'star',
                    cls: 'blog',
                    displayField: 'title',
 
                    store: {
                        type: 'tree',
 
                        fields: ['title', 'link', 'author', 'contentSnippet', 'content', {
                            name: 'leaf',
                            defaultValue: true
                        }],
 
                        root: {
                            leaf: false
                        },
 
                        proxy: {
                            type: 'jsonp',
                            url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
                            reader: {
                                type: 'json',
                                rootProperty: 'responseData.feed.entries'
                            }
                        }
                    },
 
                    detailCard: {
                        xtype: 'panel',
                        scrollable: true,
                        styleHtmlContent: true
                    },
 
                    listeners: {
                        itemtap: function(nestedList, list, index, element, post) {
                            this.getDetailCard().setHtml(post.get('content'));
                        }
                    }
                },
 
                // This is the contact page, which features a form and a button. The button submits the form.
                {
                    xtype: 'formpanel',
                    title: 'Contact Us',
                    iconCls: 'user',
                    url: 'contact.php',
                    layout: 'vbox',
 
                    items: [
                        {
                            xtype: 'fieldset',
                            title: 'Contact Us',
                            instructions: 'Email address is optional',
                            height: 285,
                            items: [
                                {
                                    xtype: 'textfield',
                                    label: 'Name',
                                    name: 'name'
                                },
                                {
                                    xtype: 'emailfield',
                                    label: 'Email',
                                    name: 'email'
                                },
                                {
                                    xtype: 'textareafield',
                                    label: 'Message',
                                    name: 'message',
                                    height: 90
                                }
                            ]
                        },
                        {
                            xtype: 'button',
                            text: 'Send',
                            ui: 'confirm',
 
                            // The handler is called when the button is tapped
                            handler: function() {
 
                                // Look up the items stack and get a reference to the first form it finds
                                var form = this.up('formpanel');
 
                                // Send an AJAX request with form data to the URL for contact.php
                                // Call the success callback if we get a non-error response from the server
                                form.submit({
                                    success: function() {
                                        // Run the callback function when a user taps the OK button
                                        Ext.Msg.alert('Thank You', 'Your message has been received', function() {
                                            form.reset();
                                        });
                                    }
                                });
                            }
                        }
                    ]
                }
            ]
        });
    }
});

开始

首先我们要做的是安装我们的应用,依照入门指南开始使用sencha touch。一旦开始使用tab panel 标签就包含了四个页面, 我们开始创建这个 UI。Sencha Touch的入口点正是launch函数中一个Ext.application方法. 关系到这个应用程序的主要部分,和应用程序逻辑。

Ext.application({
    name: 'Sencha',

    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            items: [
                {
                    title: 'Home',
                    iconCls: 'home',
                    html: 'Welcome'
                }
            ]
        });
    }
});


如果你在浏览器上运行这段代码,那么一个TabPanel标签将会展示在屏幕上。要让主页可能更受欢迎,添加一些内容,重新定位标签栏在页面的底部。默认情况下, tab bar定位在页面顶部, 但要把 tabBarPosition 配置到页面底部. 接着我们添加HTML到tems 数组下创建页面内容. 代码如下所示

Ext.application({
    name: 'Sencha',

    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',

            items: [
                {
                    title: 'Home',
                    iconCls: 'home',
                    html: [
                        '<img src="http://staging.sencha.com/img/sencha.png" />',
                        '<h1>Welcome to Sencha Touch</h1>',
                        "<p>You're creating the Getting Started app. This demonstrates how ",
                        "to use tabs, lists, and forms to create a simple app</p>",
                        '<h2>Sencha Touch</h2>'
                    ].join("")
                }
            ]
        });
    }
});


你能看到一些HTML界面,但是并不十分好看。我们给这个panel添加cls属性, 添加一些CSS类目标使东西看起来更好看。CSS存放在路径为examples/getting_started/resources/css/app.css文件里,运行下面的代码看看主页的样子。


Ext.application({
    name: 'Sencha',
 
    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',
 
            items: [
                {
                    title: 'Home',
                    iconCls: 'home',
                    cls: 'home',
 
                    html: [
                        '<img src="http://staging.sencha.com/img/sencha.png" />',
                        '<h1>Welcome to Sencha Touch</h1>',
                        "<p>You're creating the Getting Started app. This demonstrates how ",
                        "to use tabs, lists, and forms to create a simple app.</p>",
                        '<h2>Sencha Touch</h2>'
                    ].join("")
                }
            ]
        });
    }
});


添加BOLG页面

现在,我们有一个像样的主页,我们接着看下一个屏幕。保持每个页面的代码容易理解,我们创建一个标签,然后将它们组合在一起。

接着我们删除第一个选项卡,用列表代替。我们使用Google的API服务获取内容。因为有更多的代码,首先我们看一看结果,然后我们解释我们如何完成:

Ext.application({
    name: 'Sencha',
 
    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',
 
            items: [
                {
                    xtype: 'nestedlist',
                    title: 'Blog',
                    iconCls: 'star',
                    displayField: 'title',
 
                    store: {
                        type: 'tree',
 
                        fields: [
                            'title', 'link', 'author', 'contentSnippet', 'content',
                            {name: 'leaf', defaultValue: true}
                        ],
 
                        root: {
                            leaf: false
                        },
 
                        proxy: {
                            type: 'jsonp',
                            url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
                            reader: {
                                type: 'json',
                                rootProperty: 'responseData.feed.entries'
                            }
                        }
                    },
 
                    detailCard: {
                        xtype: 'panel',
                        scrollable: true,
                        styleHtmlContent: true
                    },
 
                    listeners: {
                        itemtap: function(nestedList, list, index, element, post) {
                            this.getDetailCard().setHtml(post.get('content'));
                        }
                    }
                }
            ]
        });
    }
});


保证代码没有出错和遗漏,这样才能正常运行。在这一点上,我们使用一个nestedlist替换一个pane,使用最近的博客文章sencha.com/blog获取内容填充列表。我们使用一个嵌套列表的组件,这样我们可以触摸列表查看详细。

从列表开始我们改变编辑代码:

Ext.application({
    name: 'Sencha',

    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',

            items: [
                {
                    xtype: 'nestedlist',
                    title: 'Blog',
                    iconCls: 'star',
                    displayField: 'title',

                    store: {
                        type: 'tree',

                        fields: [
                            'title', 'link', 'author', 'contentSnippet', 'content',
                            {name: 'leaf', defaultValue: true}
                        ],

                        root: {
                            leaf: false
                        },

                        proxy: {
                            type: 'jsonp',
                            url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
                            reader: {
                                type: 'json',
                                rootProperty: 'responseData.feed.entries'
                            }
                        }
                    }
                }
            ]
        });
    }
});


在上面的代码中,我们给了NestedList配置title、iconCls,displayField和store。store告诉NestedList如何获取其数据。让我们检查每个Store的配置:

  • type: tree - 创建 tree store, 供NestedList 使用.
  • fields - 从Store我们期望哪些字段定义在Bolg数据上 如 (title, content, author, and so on).
  • proxy - 定义 Store 从哪儿获取数据.
  • root - 定义一个没有叶子的根节点。因为早些时候在代码中,我们设置了叶leaf 的 defaultValue为true,我们需要覆盖根。

所有的存储Store配置,代理proxy是做最重要的工作。 我们正告诉代理 proxy 使用Google的api服务:Feed API service 返回给我们JSON-P 格式的数据. 这让我们在我们的应用中可看到博客的摘要。 (例如尝试替换 Sencha blog URL 成http://rss.slashdot.org/Slashdot/slashdot 是获取Slashdot's 食料).

代理proxy 的最后一部分定义了一个Reader。这个reader 是一个从Google请求解码响应后的有用数据实体。谷歌发回博客数据时,把它封装在一个JSON对象,看上去有点像下面的例子: 

{
    responseData: {
        feed: {
            entries: [
                {author: 'Bob', title: 'Great Post', content: 'Really good content...'}
            ]
        }
    }
}

这段条目数组代码是很重要的, 这样我们就设置实体Reader 的 rootProperty to 'responseData.feed.entries' and let the framework do the rest.

进一步

现在,我们有了自己的嵌套列表NestedList获取和显示数据,我们需要允许用户点触一个条目来阅读它。添加这个功能,我们需要添加两个配置到NestedList,如下:

{
    xtype: 'nestedlist',
    //all other configurations as above

    detailCard: {
        xtype: 'panel',
        scrollable: true,
        styleHtmlContent: true
    },

    listeners: {
        itemtap: function(nestedList, list, index, element, post) {
            this.getDetailCard().setHtml(post.get('content'));
        }
    }
}

上面代码中,我们建了一个detailCard, which is a useful feature of Nested List 当用户触点不同条目显示不同内容. 将detailCard配置styleHtmlContent 属性 变成可以滚动的 Panel 可让文本内容看上去更加舒服.

最后一步是添加一个itemtap 侦听器,一旦一个条目触碰后将调用一个函数。函数将detailCard的HTML内容设置上显示。框架将DetailCard推送到视图上显示成帖子。这是我们唯一不得不写的代码行去使博客阅读器工作。

创建触点形式

我们做的最后一件事是对我们的应用程序创建一个触点形式。我们把用户的名称、电子邮件地址和信息,集中在FieldSet 让它看起来不错。这个功能的代码如下:

Ext.application({
    name: 'Sencha',
 
    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',
 
            items: [
                {
                    title: 'Contact',
                    iconCls: 'user',
                    xtype: 'formpanel',
                    url: 'contact.php',
                    layout: 'vbox',
 
                    items: [
                        {
                            xtype: 'fieldset',
                            title: 'Contact Us',
                            instructions: '(email address is optional)',
                            height: 285,
                            items: [
                                {
                                    xtype: 'textfield',
                                    label: 'Name'
                                },
                                {
                                    xtype: 'emailfield',
                                    label: 'Email'
                                },
                                {
                                    xtype: 'textareafield',
                                    label: 'Message'
                                }
                            ]
                        },
                        {
                            xtype: 'button',
                            text: 'Send',
                            ui: 'confirm',
                            handler: function() {
                                this.up('formpanel').submit();
                            }
                        }
                    ]
                }
            ]
        });
    }
});


此时我们创建了一个包含 fieldset的 form 。field set 包含了三个 fields - name, email address,  message. 我们用VBox layout 布局排列他的所属条目,一上一下垂直显示在页面上.

我们在panel底部添加一个 handler 按钮,触发程序。这个按钮使用的是 up 方法,该方法返回包含按钮的表单面板。接着我们点击 submit 提交表单,将表单发送到指定的URL ('contact.php').

集成在一起

分别创建每个视图后,我们将他们凝聚在一起成为一个完整的应用程序:

// We've added a third and final item to our tab panel - scroll down to see it
Ext.application({
    name: 'Sencha',
 
    launch: function() {
        Ext.create("Ext.tab.Panel", {
            fullscreen: true,
            tabBarPosition: 'bottom',
 
            items: [
                {
                    title: 'Home',
                    iconCls: 'home',
                    cls: 'home',
                    html: [
                        '<img width="65%" src="http://staging.sencha.com/img/sencha.png" />',
                        '<h1>Welcome to Sencha Touch</h1>',
                        "<p>We're creating the Getting Started app, which demonstrates how ",
                        "to use tabs, lists, and forms to create a simple app.</p>",
                        '<h2>Sencha Touch</h2>'
                    ].join("")
                },
                {
                    xtype: 'nestedlist',
                    title: 'Blog',
                    iconCls: 'star',
                    displayField: 'title',
 
                    store: {
                        type: 'tree',
 
                        fields: [
                            'title', 'link', 'author', 'contentSnippet', 'content',
                            {name: 'leaf', defaultValue: true}
                        ],
 
                        root: {
                            leaf: false
                        },
 
                        proxy: {
                            type: 'jsonp',
                            url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
                            reader: {
                                type: 'json',
                                rootProperty: 'responseData.feed.entries'
                            }
                        }
                    },
 
                    detailCard: {
                        xtype: 'panel',
                        scrollable: true,
                        styleHtmlContent: true
                    },
 
                    listeners: {
                        itemtap: function(nestedList, list, index, element, post) {
                            this.getDetailCard().setHtml(post.get('content'));
                        }
                    }
                },
                // this is the new item
                {
                    title: 'Contact',
                    iconCls: 'user',
                    xtype: 'formpanel',
                    url: 'contact.php',
                    layout: 'vbox',
 
                    items: [
                        {
                            xtype: 'fieldset',
                            title: 'Contact Us',
                            instructions: '(email address is optional)',
                            height: 285,
                            items: [
                                {
                                    xtype: 'textfield',
                                    label: 'Name'
                                },
                                {
                                    xtype: 'emailfield',
                                    label: 'Email'
                                },
                                {
                                    xtype: 'textareafield',
                                    label: 'Message'
                                }
                            ]
                        },
                        {
                            xtype: 'button',
                            text: 'Send',
                            ui: 'confirm',
                            handler: function() {
                                this.up('formpanel').submit();
                            }
                        }
                    ]
                }
            ]
        });
    }
});

你可以在Sencha Touch SDK路径:examples/getting_started 找到完整的源代码 .





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值