Sencha Touch 历史支持

路由、深链接以及后退按钮 Routing, Deep Linking and the Back Button

Sencha Touch 2 提供完整的历史与深链接的支持,使得我们的 Web 应用拥有以下两点大的好处:

  • 浏览器的“后退”按钮在你的应用中有效了,也就是说,虽然按下了后退键,但浏览器并不会立刻刷新,而是仍停留在当前的页面中。
  • 可以使用“深链接”了,也就是说,可以分配的一个 url,直达制定的页面(在同一个页面中)。

上述功能综述之,就是为了更好地与原生程序相贴近,务求达到无差别的用户体验——这一点,尤其体现在能够提供“返回键”的 Android 机器上面。

设置路由器 Setting up routes

为你的应用安排的历史记录可以说一点都不困难,主要集中在如何理解的路由器(routes)的概念之上。路由器,简言之,用于定义某一 url 与用户控制器动作之间的映射关系——所谓映射关系,只要在浏览器的地址栏中输入一个地址,对应的控制器便会自动执行某组逻辑动作。咱们看看一个简单的控制器:

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

        config: {
            routes: {
                'products/:id': 'showProduct'
            }
        },

        showProduct: function(id) {
            console.log('showing product ' + id);
        }
    });

通过指定 {@link Ext.app.Controller#routes routes},当诸如“#products/123” 这样的 url 输入到浏览器时就会通知 Main 控制器。详细点说,就是你的域名是 http://myapp.cpm,然后任何的 http://myapp.com/#products/123、 http://myapp.com/#products/456 或 http://myapp.com/#products/abc 这般的链接,其实终归自动进入到 showProduct 函数的执行环境中去。

当 showProduct 被执行时,其参数就是那个 url 解析而致的。有否注意到路由器中的“:id”部分,因为我们约定,有冒号“:”即表示后面跟的是为一个参数,路由器内部解析好 url 就会得到这个参数然后送入到你所写的函数中去。值得注意的是,该参数总是字符类型(无需多言,url 本身亦是字符类型),于是浏览器得到的“http://myapp.com/#products/456 or http://myapp.com/#products/abc”亦即等于调用 showProduct('456')。

路由器合法的格式多种多样,构成了不同参数的映射关系,例如:

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

        config: {
            routes: {
                'products/:id': 'showProduct',
                'products/:id/:format': 'showProductInFormat'
            }
        },

        showProduct: function(id) {
            console.log('showing product ' + id);
        },

        showProductInFormat: function(id, format) {
            console.log('showing product ' + id + ' in ' + format + ' format');
        }
    });

第一个路由很简单,前面已经说了说;第二个路由接纳 #products/123/pdf 这样的输入,转到 showProductInFormat 函数,便在在控制台中记录了 showing product 123 in pdf format 这样的输出。另外,id、format 也是按照路由定义中的顺序送入函数中。

当然了,实际中你写的并不像我们这里教学例子的那么简单。大家想该怎么做了吗?就是在控制器中写你的业务逻辑,获取数据啊、更新UI啊的任务……

高级路由器 Advanced Routes

路由器支持通贝符(wildcards)。默认下,通贝符表示不分字符或数字。假设“products/:id/edit”可以接纳“#products/123/edit”但不接纳“#products/a ,fd.sd/edit”,因为后者包含的空格、逗号、句号均不在通贝符涵盖的类型之列。

不过有时我们想自定义复杂一些的规制,——这没问题,我们分配一个配置项对象给 routes 对象而不是字符串,好比如下:

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

        config: {
            routes: {
                'file/:filename': {
                    action: 'showFile',
                    conditions: {
                        ':filename': "[0-9a-zA-Z\.]+"
                    }
                }
            }
        },

        //opens a new window to show the file
        showFile: function(filename) {
            window.open(filename);
        }
    });

当然不直接分配方法名称的名称还需要说明你要调用哪个函数,就写在配置项对象的 action 属性中。此外关键的是,条件配置项 {@link Ext.app.Route#conditions conditions} 其 key 为对应的 token,然后 value 为期望的规制。结果,假设一 url 系  http://myapp.com/#file/someFile.jpg,路由器解析后执行 showFile 函数,并送入“someFile.jpg”的参数。

复原状态 Restoring State

前面为大家介绍了定义路由器映射规制的相关知识后,接下来,就是详细讲讲具体的应用了。因为既然是“单页面的应用程序”的缘故,所以我们不轻易地产生一个 url 对应一张页面——如果我们进入首页后,一步步查找分类然后再找到那笔记录,——岂不是很累?所以说,由框架设定一套 url 规制便很有必要了。我们看看下面一个简单的例子,比如还是进入 http://myapp.com/#products/123,我们修改一下 Product 控制器如下:

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

        config: {
            refs: {
                main: '#mainView'
            },

            routes: {
                'products/:id': 'showProduct'
            }
        },

        /**
         * products/:id 路由器的终点。获取一个货物的详细信息然后 push 的新视图。Endpoint for 'products/:id' routes. Adds a product details view (xtype = productview)
         * into the main view of the app then loads the Product into the view
         *
         */
        showProduct: function(id) {
            var view = this.getMain().add({
                xtype: 'productview'
            });

            MyApp.model.Product.load(id, {
                success: function(product) {
                    view.setRecord(product);
                },
                failure: function() {
                    Ext.Msg.alert('Could not load Product ' + id);
                }
            });
        }
    });

这里的 products/:id 终点就会立刻添加一新视图到主视图中(如非导航类可以是其他的 TabPanel 控件),进而由 model 类(MyApp.model.Product)向服务器获取货物的详细信息。这一过程是异步的过程,所以我们分配了两个回调函数,分别对应成功(渲染 货物 UI)与失败的情形。

不同的应用有不同的复原状体逻辑,一些深入链接的情形。官方例子 Kitchen Sink 就是一个很好的例子,尤其它采用了  NestedList 方式的导航很能说明问题,并且有手机和平板的两种适应场景。具体怎么办到的?请到 Kitchen Sink 例子 app/controller/phone/Main.js and app/controller/tablet/Main.js 的 showView() 源码看看吧。

Sharing urls across Device Profiles

无论你有多少套<a href="#!/guide/profiles">设备描述 Device Profiles</a>,但一般来说你都会只使用路由结构,也就是说,你在 iPhone 上看到一页面,发觉不错,然后想共享该 url 给别人的话,那么直接把 url 复制给别人即可,无须担心人家的是否手机抑或平板。因此,建议分别在手机子类上写一套路由的配置,然后在平板子类上写一套路由的配置:

    Ext.define('MyApp.controller.Products', {
        extend: 'Ext.app.Controller',
        config: {
            routes: {
                'products/:id': 'showProduct'
            }
        }
    });

手机版的显示方式有所不同,于是,我们写出 showProduct 函数的手机版实现:

    Ext.define('MyApp.controller.phone.Products', {
        extend: 'MyApp.controller.Products',

        showProduct: function(id) {
            console.log('showing a phone-specific Product page for ' + id);
        }
    });

平板电脑的话,在其子类中写出特定的实现:

    Ext.define('MyApp.controller.tablet.Products', {
        extend: 'MyApp.controller.Products',

        showProduct: function(id) {
            console.log('showing a tablet-specific Product page for ' + id);
        }
    });
时间: 2024-11-09 03:49:36

Sencha Touch 历史支持的相关文章

Sencha Touch跨域问题解决

之前对于跨域问题仅有粗浅的认识,一般是浏览器层面出于安全性的考虑,不允许调用其他页面的对象.这次在Sencha Touch中解决这个问题额外花掉不少时间. 解决的方法大概就是: 修改服务器的header: JsonP.JsonP方法是一种非官方的解决方案,只支持Get方法,需要服务器端根据callback参数返回不同的内容.返回的内容不是标准的json格式,对服务器端的改动会比较麻烦.我选择了修改服务器返回的header的方法. 1. 修改header的Access-Control-Allow-

sencha touch项目怎么加chorm内核

问题描述 sencha touch项目怎么加chorm内核 新建sencha项目->添加phonegap支持->替换内核为chorm->修改加载网页地址为super.loadUrl(""file:///android_asset/www/index.html"");运行失败,求助

Sencha Touch 2 Release Candidate 发布总结

这次发布新版的 ST2(下载:http://cdn.sencha.io/touch/sencha-touch-2-rc.zip),将为我们带来什么呢?以下就我阅读了 Sencha 官方博客文章后,做的一些笔记. 一.新提供了六个例子 新提供例子的话不足为奇,若那些是完整的实例完全来呈现给用户的话,则最好不过.这次发布的 ST 真的做到这点,都是一些实际上应用到的例子.这不,咱们要快速开发的朋友则有福了,马上有现成的例子可供参考--些许改动即可. 二.Ext.Direct 话说无论 ExtJS 还

预览 Sencha Touch 2:原生包和性能改进

http://www.sencha.com/blog/sencha-touch-2-what-to-expect/ 作者:Aditya Bansod 译者:Sp42(zhangxin09) 今天,我们提前为大家介绍一下 Sencha Touch  2.0的新功能.我们十分雀跃地告诉大家将要到来的新发布,我们希望你们通过开发了一些给力的移动应用来实际参与分享我们这一份雀跃. 让我们先快速回顾一下.自去年发布 Sencha Touch 最初版本,这一期间,HTML5 和移动网络的发展也突飞猛进.许多

Sencha Touch v1.1发布 第一个HTML5的Mobile App框架

前不久基于JavaScript编写的Ajax框架ExtJS,将现有的ExtJS整合JQTouch.Raphaël库,推出适用于最前沿Touch Web的Sencha Touch框架,该框架是世界上第一个基于HTML5的Mobile App框架.同时,ExtJS更名为Sencha,JQTouch的创始人David Kaneda,以及Raphaël的创始人也已加盟Sencha团队. Sencha Touch可以让你的Web App看起来像Native App.美丽的用户界面组件和丰富的数据管理,全部

sencha touch dataview 数据加载问题

问题描述 sencha touch dataview 数据加载问题 在使用sencha touch时遇到个问题.dataview 控件第一次加载数据能显示,第二次加载数据无法显示,这时我随便点一下界面任意一个控件(不执行任何操作)这时数据又显示出来了... 查阅了很多资料都没解决. 解决方案 http://blog.sina.com.cn/s/blog_6158283f0100uep4.html

sencha touch在google浏览器中出现的问题?

问题描述 sencha touch在google浏览器中出现的问题? 使用的google chrome 22 滚动条滚动时,文字下方会出现部分文章一直卡在那里.但是google chrome 30就不会出现,怎么在不换浏览器的情况下.解决这个问题.

sencha touch2.0和sencha touch 2.1的区别在哪

问题描述 sencha touch2.0和sencha touch 2.1的区别在哪 sencha touch 2.1能兼容sencha touch 2.0所有的方法吗

关于sencha touch 中build时出现的错误

问题描述 关于sencha touch 中build时出现的错误 大神帮忙看看,新建的项目,build时出现这个错误,我真的看不懂呀.初学者.