移动Web应用开发技术讲解:Sencha Touch 1.1

移动开发
移动应用主要有两种模式:本地应用和移动Web应用。目前以本地应用最为流行,而移动Web应用也日趋流行。这两种模式相当于我们经常说的CS架构和BS架构。本地应用,简单来说就是通过使用手机操作系统支持的程序语言(例如:iphone的iOS系统使用Objective-C语言,google的android系统则使用Java语言)编写软件,然后安装在手机上的应用软件。移动Web应用,简单来理解就是针对移动终端优化过的Web 站点,终端用户通过支持Html5、Css3、JavaScript标准的Webkit内核浏览器访问部署在服务器的Web应用。

目录

***章 移动应用现状

1.1移动应用模式及其各自优劣势

1.2移动Web应用开发框架

第二章 Sencha Touch框架的介绍

第三章 Sencha Touch***个例子

3.1发环境的搭建与调试工具

3.2***例子

第四章 Sencha Touch布局介绍

4.1BoxLayout、HBoxLayout、VBoxLayout(箱子布局)

4.2FitLayout(自适应布局)

4.3CardLayout(卡片式布局)

第五章 Sencha Touch表单

5.1表单元素

5.2表单常用属性与常用方法

5.3表单数据加载

5.4表单数据提交

第六章 数据的获取

第七章 总结

 

正文

 

***章 移动应用现状

1.1移动应用模式及其各自优劣势

移动应用主要有两种模式:本地应用和移动Web应用。目前以本地应用最为流行,而移动Web应用也日趋流行。这两种模式相当于我们经常说的CS架构和BS架构。

本地应用,简单来说就是通过使用手机操作系统支持的程序语言(例如:iphone的iOS系统使用Objective-C语言,google的android系统则使用Java语言)编写软件,然后安装在手机上的应用软件。本地应用开发可以直接调用手机操作系统的 API(包括UI界面接口、摄像头接口、加速度传感器接口、读写内存地址等等),因此响应速度更快、用户体验更好(界面可制作得很优雅、操作非常流畅)、不受网络的限制。只是目前手机操作系统众多:苹果的iOS、谷歌的Android、微软的Window Phone 7、诺基亚的Symbian、其他厂商的webOS、黑莓等,若一款应用软件想在不同的操作系统上运行,则需要针对不同的平台重新开发(有可能还需要根据手机屏幕的大小进行特定设置),这是一件非常痛苦的事情。

简而言之,本地应用具有可以充分发挥设备硬件和操作系统的特性,运行效率高,完全不受网络限制的优势;也具有开发周期较长、成本较高(需要为各种操作系统进行开发)、不同终端的适配度不理想的劣势。

移动Web应用,简单来理解就是针对移动终端优化过的Web 站点,终端用户通过支持Html5、Css3、Javascript标准的Webkit内核浏览器访问部署在服务器的Web应用。因此移动Web应用具有跨平台、多种终端的广泛适配(降低了开发周期和成本)、实时调整与完善、Web开发者可以快速上手等优势;当然限于手机操作系统的安全限制,移动Web应用还是在硬件功能调用方面有所滞后(譬如:目前还不能直接调用手机的加速度传感器、摄像头)、复杂的用户界面效果难以实现等劣势。不过,随着HTML5的不断发展,移动Web应用也将更加强大。

1.2移动Web应用开发框架

目前主要的移动Web应用开发框架有:Sencha Touch、JQuery Mobile以及PhoneGap。下面简单介绍一下这三个开发框架。

Sencha Touch

Sencha Touch框架是世界上***个基于HTML 5的Mobile App框架,它可以让Web App看起来像Native App。美丽的用户界面组件和丰富的数据管理,全部基于***的HTML 5和CSS3的 WEB标准,全面兼容Android和iOS设备。Sencha Touch相对来说是一个重量级的移动Web应用框架,适合用于开发业务逻辑比较复杂的移动Web应用。优点:针对触摸屏丰富的UI设计支持复杂交互、纯JavaScript搞定布局、版本稳定性能尚可。

JQuery Mobile

JQuery Mobile 是 jQuery 在手机上和平板设备上的版本,不仅给主流移动平台带来jQuery核心库,而且发布一个完整统一的jQuery移动UI框架,支持全球主流的移动平台,它属于一个轻量级的移动Web应用框架,可以非常便捷的开发出基于Html5的移动网站。优点:超多平台支持、入门简单传统div布局;缺点:UI支持比较简单不适合复杂交互。

PhoneGap

PhoneGap是一个用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台。它使开发者能够利用iPhone,Android,Palm,Symbian,WP7,Bada和Blackberry智能手机的核心功能——包括地理定位,加速器,联系人,声音和振动等,此外PhoneGap拥有丰富的插件,可以以此扩展无限的功能。PhoneGap是免费的,但是它需要特定平台提供的附加软件,例如iPhone的iPhone SDK,Android的Android SDK等,也可以和DW5.5配套开发。使用PhoneGap只比为每个平台分别建立应用程序好一点点,因为虽然基本代码是一样的,但是你仍然需要为每个平台分别编译应用程序。目前PhoneGap缺陷还是蛮多的,比如运行速度慢,UI反应延时。假以时日,随着技术的发展,问题会得到解决的。

具体选择那种移动Web框架,需要从项目组人员技术及业务需求情况出发进行选择:

1、功能简单,只想让现有网站支持手机和平板电脑等移动设备,可考虑jQuery Mobile框架,入门简单而且支持较多平台。

2、想做客户端而且跨平台、丰富的交互,且项目组有熟悉ExtJS的开发人员,Sencha Touch是个不错的选择。

3、如果需要调用到手机操作系统的API,可以把Sencha Touch(或JQuery Mobile)与PhoneGap进行整合开发。

第二章Sencha Touch框架的介绍

Sencha Touch框架是世界上***个基于HTML 5的Mobile App框架,也是目前为止所发现的***大的应用于移动平台的框架,它将自己定位为框架(Framework)而不是类库(Library),也可以充 分印证这一点。相信随着Sencha Touch的不断发展,移动平台的Web App用户体验设计会得到大幅提升,同时也会对HTML 5和CSS3在移动平台上的普及推广产生很大的促进作用。可以预见,随着HTML 5愈加强大的功能,未来的移动应用将会逐渐向Web App时代迈进。

Sencha Touch是原来的Extjs项目组与jQTouch和Raphael两大项目强强联手后,打造的全新Mobile App框架。

Sencha Touch可以让你的WebApp看起来像Native App。美丽的用户界面组件和丰富的数据管理,全部基于***的HTML 5和CSS3的 WEB标准,全面兼容Android和iOS设备。

Sencha Touch官方列出的几大特性有:

◆基于***的WEB标准 – HTML 5,CSS3,JavaScript。整个库在压缩和gzip后大约80KB,通过禁用一些组件还会使它更小。

◆支持世界上***的设备。Beta版兼容Android和iOS,Android上的开发人员还可以使用一个专为Android定制的主题。

◆增强的触摸事件。在touchstart等标准事件基础上,增加了一组自定义事件数据集成,如tap、swipe、pinch、rotate等。

◆数据集成。提供了强大的数据包,通过Ajax、JSONp、YQL等方式绑定到组件模板,写入本地离线存储。

在查看Sencha Touch自带的Demo以及实际使用中,还可以发现具体不错的功能点:

◆HTML 5地理定位

◆重力感应滚动

◆滚动Touch事件

◆为移动优化的表单元素

◆JSONP代理(跨域数据读取)

◆YQL数据代理(类似查询语言式数据获取)

◆遮罩弹出层

◆Multi-Card布局

◆CSS3 Transitions

◆Tab组件以及滚动列表视图

3.1发环境的搭建与调试工具

Sencha Touch的开发环境搭建相当简单,在Eclipse中创建一个Web项目,定好项目的目录结构后,引入Sencha Touch的类库。

Sencha Touch的调试工具,我主要是使用google的chrome浏览器(***版本是chrome15.0.87),下载地址:http://www.google.cn/Chrome

关于该浏览器及其调试的使用方法可参考:http://www.google.com/support/chrome/bin/static.py?page=guide.cs&guide=29302&hl=cn&printable=1

3.2 ***例子

按我们的通用平台架构,视图层使用了Freemarker模板,因此前台页面一般分为ftl文件和js文件。根据Sencha Touch的特点以及我自己的思考,一个模块一般只需用一个ftl文件,然后在这个文件引入所需用的自定义的js文件(通用的组件js文件,可以考虑放入到freemarker模板中)。

以下就是***个例子的ftl(stFirstExample.ftl)文件内容:

  1. <@c2.touch title="" cssList=[] jsList=['example/stFirstExample.js']> 
  2.  
  3. </@c2.touch> 
  4.  
  5. cssList是用来引入自定义的css3样式文件,jsList是用来引入所需的js文件。 
  6.  
  7. js(stFirstExample.js)文件内容: 
  8.  
  9. //创建***个示例的命名空间 
  10.  
  11. Ext.ns('example', 'example.views'); 
  12.  
  13. //通过Ext.setup方法来参加一个Sencha Touch应用页面,setup方法里可以配置很多属性 
  14.  
  15. Ext.setup({ 
  16.  
  17. statusBarStyle: 'light', 
  18.  
  19. onReady: function() { 
  20.  
  21. //工具栏-toolbar 
  22.  
  23. varfunBar = { 
  24.  
  25. xtype: 'toolbar', 
  26.  
  27. title: 'ST ***个例子', 
  28.  
  29. dock: 'top', //工具栏放置的位置(必须的属性):top-上,bottom-下,left-左,right-右 
  30.  
  31. scroll: 'horizontal', 
  32.  
  33. height:30, 
  34.  
  35. items: [{ 
  36.  
  37. xtype:'button', 
  38.  
  39. text: '桌面', 
  40.  
  41. ui: 'back', 
  42.  
  43. //iconMask:true, 
  44.  
  45. //iconCls:'home', 
  46.  
  47. style:btStyle, 
  48.  
  49. handler:function(){ 
  50.  
  51. window.location = prefix + '/index.action'; 
  52.  
  53.  
  54. }] 
  55.  
  56. }; 
  57.  
  58. //主界面 
  59.  
  60. varviewport = new Ext.Panel({ 
  61.  
  62. fullscreen:true, 
  63.  
  64. monitorOrientation:true, 
  65.  
  66. dockedItems:[funBar], 
  67.  
  68. items:[{ 
  69.  
  70. html:'hello kitty......' 
  71.  
  72. }] 
  73.  
  74. }); 
  75.  
  76.  
  77. }); 

可以看到,stFirstExample.js 的***行代码创建了两个命名空间:example和example.views。

第二行代码调用了 Ext.setup() 方法,用以建立一个触控设备的 Web 页面,该方法可以为我们的应用设置不同的启动属性和行为:

◆icon,设置该应用默认的图标;

◆ tabletStartupScreen,该属性设置在平板电脑上的启动图标;

◆ phoneStartupScreen,该属性设置在智能手机上的启动图标;

◆glossOnIcon,该属性设置是否在默认图标上呈现光环效果;

◆onReady,该方法会在页面加载完毕,浏览器中的 DOM 模型已经建立完成时被调用。由于为了保证程序在运行时所依赖的JavaScript 文件都已经加载完毕,我们一般将应用启动的逻辑置于该方法内,类似于 Java 程序的 main 方法。

在onReady方法中,有一个地方我们需用注意的:

◆Ext.Panel对象的dockedItems属性,通过它可以在panel中放置工具栏等组件,可选值有:top-上,bottom-下,left-左,right-右。fullscreen属性为true(默认为false)则强制该panel充满整个屏幕。monitorOrientation属性为true则可以让panel面板监听屏幕方向发生变化时候的事件。

◆dockedItems属性里的对象,必须由docked属性,用以指定放置的位置。

当然js文件也可以通过另外一种方式创建应用:

  1. //通过Application来创建一个应用 
  2.  
  3. var FirstApp = new Ext.Application({ 
  4.  
  5. name: 'firstApp'
  6.  
  7. useLoadMask: true
  8.  
  9. launch: function () { 
  10.  
  11. //工具栏-toolbar 
  12.  
  13. varfunBar = { 
  14.  
  15. xtype: 'toolbar'
  16.  
  17. title: 'ST ***个例子'
  18.  
  19. dock: 'top'//工具栏放置的位置(必须的属性):top-上,bottom-下,left-左,right-右 
  20.  
  21. scroll: 'horizontal'
  22.  
  23. height: 30, 
  24.  
  25. items: [{ 
  26.  
  27. xtype: 'button'
  28.  
  29. text: '桌面'
  30.  
  31. ui: 'back'
  32.  
  33. //iconMask:true, 
  34.  
  35. //iconCls:'home', 
  36.  
  37. style: btStyle, 
  38.  
  39. handler: function(){ 
  40.  
  41. window.location= prefix + '/index.action'
  42.  
  43.  
  44. }] 
  45.  
  46. }; 
  47.  
  48. //主界面 
  49.  
  50. var viewport = newExt.Panel({ 
  51.  
  52. fullscreen: true
  53.  
  54. monitorOrientation:true
  55.  
  56. dockedItems: [funBar], 
  57.  
  58. items: [{ 
  59.  
  60. html: 'hellokitty......' 
  61.  
  62. }] 
  63.  
  64. }); 
  65.  
  66.  
  67. }); 

Ext.Application实例的初始化,意味者一个Sencha Touch应用的建立,这个类的实例化后,会自动创建一个全局的变量FirstApp,并且同时建立了如下的命名空间:

firstApp

firstApp.views

firstApp.stores

firstApp.models

firstApp.controllers

而launch的方法只会运行一次。

第四章Sencha Touch布局介绍

在我们的Web应用开发中,页面的排版、布局很重要,用户就是通过页面操作来完成日常工作的。如果界面布局不合理、操作不方便,用户也不会对系统有好的印象、甚至有可能影响一个项目的成败。我自己的经验是,在开发某个功能模块时,除了仔细属性该模块的功能需求和业务需求外,还会在草稿纸上简单的把该功能的布局画出来(如果美工已经制作有页面模型外)。例如:

Sencha Touch的布局类似Extjs中的布局,常用的有:BoxLayout、HBoxLayout、VBoxLayout、FitLayout、CardLayout。

4.1 BoxLayout、HBoxLayout、VBoxLayout(箱子布局)

BoxLayout是箱子布局,该布局类似于药店里放置中草药的大柜子里一个个小箱子那样,把组件放置在容器中(Container)中。BoxLayout是HBoxLayout和VBoxLayout这两个布局类的父类,一般很少直接使用。

◆HBoxLayout是水平箱子布局,即把组件横排的放置在容器中。

代码清单:

  1. var viewport = newExt.Panel({ 
  2.  
  3. fullscreen:true
  4.  
  5. //width: 500, 
  6.  
  7. //height:200, 
  8.  
  9. margin: '0 0 0 0'
  10.  
  11. layout: { 
  12.  
  13. type: 'hbox'//指定layout布局方式为HBoxLayout 
  14.  
  15. align: 'stretch' //布局里的‘小容器’拉伸,类似window桌面图片那样,拉伸到整个页面大 
  16.  
  17. }, 
  18.  
  19. items: [{ 
  20.  
  21. flex: 1, //所占宽度的比率 
  22.  
  23. //height: 200, 
  24.  
  25. style: 'border:1pxred solid'//自定义样式 
  26.  
  27. margin: '0 20 0 0'//设置边框距离 
  28.  
  29. items: [{ 
  30.  
  31. xtype:'button'
  32.  
  33. text:'***'
  34.  
  35. margin:6 
  36.  
  37. }] 
  38.  
  39. },{ 
  40.  
  41. flex: 2, 
  42.  
  43. //height: 200, 
  44.  
  45. style: 'border:1pxred solid'
  46.  
  47. margin: '0 20 0 0'
  48.  
  49. html: '<divstyle="border:1px red dashed;margin:6px;">第二个小箱子</div>' 
  50.  
  51. },{ 
  52.  
  53. flex: 3, 
  54.  
  55. //height: 200, 
  56.  
  57. style: 'border:1pxred solid'
  58.  
  59. items: [{ 
  60.  
  61. xtype:'button'
  62.  
  63. text:'第三'
  64.  
  65. margin:6 
  66.  
  67. }] 
  68.  
  69. }] 
  70.  
  71. }); 

有两个属性需要关注一下:

◆align: 'stretch',该属性是设置容器里‘小容器’的对齐方式。

◆flex属性是设置‘小容器’的宽度比率,具体的计算方式请参看文档。

当然还有其他的属性,例如:style、margin、padding,这些属性主要是设置样式的。

◆VBoxLayout垂直箱子布局,即把组件垂直的放置在容器中。

代码清单:

  1. var viewport = newExt.Panel({ 
  2.  
  3. fullscreen: true
  4.  
  5. //width: 500, 
  6.  
  7. //height:200, 
  8.  
  9. margin: '0 0 0 0'
  10.  
  11. layout: { 
  12.  
  13. type: 'vbox'//指定layout布局方式为VBoxLayout 
  14.  
  15. align:'stretch' //布局里的‘小容器’拉伸 
  16.  
  17. }, 
  18.  
  19. items: [{ 
  20.  
  21. flex: 1, //所占宽度的比率 
  22.  
  23. //height: 200, 
  24.  
  25. style: 'border:1pxred solid'
  26.  
  27. margin: '0 0 10 0'
  28.  
  29. items: [{ 
  30.  
  31. xtype:'button'
  32.  
  33. text:'***'
  34.  
  35. margin: 6 
  36.  
  37. }] 
  38.  
  39. },{ 
  40.  
  41. flex: 2, 
  42.  
  43. //height: 200, 
  44.  
  45. style: 'border:1pxred solid'
  46.  
  47. margin: '0 0 10 0'
  48.  
  49. html: '<divstyle="border:1px red dashed;margin:6px;">第二个小箱子</div>' 
  50.  
  51. },{ 
  52.  
  53. flex: 3, 
  54.  
  55. //height: 200, 
  56.  
  57. style: 'border:1pxred solid'
  58.  
  59. items: [{ 
  60.  
  61. xtype:'button'
  62.  
  63. text:'第三'
  64.  
  65. margin:6 
  66.  
  67. }] 
  68.  
  69. }] 
  70.  
  71. }); 

4.2 FitLayout(自适应布局)

FitLayout是布局的基础类,对应面板布局配置项的名称为fit,使用fit布局将使面板子元素自动充满容器,如果在当前容器中存在多个子面板则只有一个会被显示。

代码清单:

  1. var viewport = newExt.Panel({ 
  2.  
  3. fullscreen: true
  4.  
  5. //width: 500, 
  6.  
  7. //height:200, 
  8.  
  9. margin: '0 0 0 0'
  10.  
  11. layout: 'fit'//指定layout布局方式为FitLayout 
  12.  
  13. items: [{ 
  14.  
  15. style: 'border:1pxred solid'
  16.  
  17. html: '<div style="border:1pxred dashed;margin:6px;">***个小箱子</div>' 
  18.  
  19. },{ 
  20.  
  21. style: 'border:1pxblue solid'
  22.  
  23. html: '<div style="border:1pxred dashed;margin:6px;">第二个小箱子</div>' 
  24.  
  25. }] 
  26.  
  27. }); 

4.3 CardLayout(卡片式布局)

CardLayout在Sencha Touch中是最常用的布局,模仿本地应用的页面转换效果主要通过它来体现出来。它是扩展自FitLayout布局,对应面板布局配置项的名称为card。该布局会包含多个子面板,但任何时候都只有一个子面板处于显示状态,这种布局经常用来制作向导和标签页。

各个字面板之间切换的途径是调用setActiveItem方法,该方法接收一个子面板对象或id、索引作为参数。

代码清单:

  1. //工具栏-toolbar 
  2.  
  3. var funBar = { 
  4.  
  5. xtype: 'toolbar'
  6.  
  7. title: 'CardLayout例子'
  8.  
  9. dock: 'top'//工具栏放置的位置(必须的属性):top-上,bottom-下,left-左,right-右 
  10.  
  11. scroll: 'horizontal'
  12.  
  13. height: 30, 
  14.  
  15. items: [{ 
  16.  
  17. xtype: 'button'
  18.  
  19. text: '桌面'
  20.  
  21. ui: 'back'
  22.  
  23. //iconMask:true, 
  24.  
  25. //iconCls:'home', 
  26.  
  27. style: btStyle, 
  28.  
  29. handler: function(){ 
  30.  
  31. window.location = prefix + '/index.action'
  32.  
  33.  
  34. },{ 
  35.  
  36. xtype: 'button'
  37.  
  38. text: '***个子面板'
  39.  
  40. style: btStyle, 
  41.  
  42. handler: function(){ 
  43.  
  44. changeItem('p1'); 
  45.  
  46.  
  47. },{ 
  48.  
  49. xtype: 'button'
  50.  
  51. text: '第二个子面板'
  52.  
  53. style: btStyle, 
  54.  
  55. handler: function(){ 
  56.  
  57. changeItem('p2'); 
  58.  
  59.  
  60. }] 
  61.  
  62. }; 
  63.  
  64. //主界面 
  65.  
  66. var viewport = newExt.Panel({ 
  67.  
  68. fullscreen: true
  69.  
  70. margin: '0 0 0 0'
  71.  
  72. layout: 'card'//指定layout布局方式为CardLayout 
  73.  
  74. activeItem: 0, 
  75.  
  76. dockedItems: [funBar], 
  77.  
  78. items: [{ 
  79.  
  80. id: 'p1'
  81.  
  82. style: 'border:1pxred solid'
  83.  
  84. html: '<divstyle="border:1px red dashed;margin:6px;">***个小箱子</div>' 
  85.  
  86. },{ 
  87.  
  88. id: 'p2'
  89.  
  90. style: 'border:1pxblue solid'
  91.  
  92. html: '<divstyle="border:1px red dashed;margin:6px;">第二个小箱子</div>' 
  93.  
  94. }] 
  95.  
  96. }); 
  97.  
  98. //切换子面板 
  99.  
  100. var changeItem = function(id){ 
  101.  
  102. viewport.setActiveItem(id, 'slide'); 
  103.  
  104. }; 
  105.  
  106. }; 

第五章Sencha Touch表单

用户与系统的交互,绝大部分是通过表单来进行。Sencha Touch的表单与Extjs的表单类似,只是新增了一些html5的元素,例如:url输入框、email输入框、search输入框、Number输入框、slider、toggle等。

5.1 表单元素

表单元素有以下这些,其中有很多都是大家所熟悉的,在此就不做多说明,主要是说明一些新的表单元素及其常用属性,其他(包括组件的方法、事件等)的请大家参照api文档:

◆Text文本输入框

简单的文本输入框,xtype为textfield(注意与extjs的不同哦)。常用的属性有:

id:组件的唯一id,id属性是全部组件都有的。

name:组件的名称,name属性也是全部组件都有的。

label:组件显示的标记(注意与extjs的不同哦)。

labelAlign:label放置的位置,可选值有:left、right、top、bottom。

placeHolder: 输入框为空值时自动显示的值,相当于extjs的emptyText属性。

maxLength:输入框可以输入内容的***长度。

autoCapitalize:是否开启首字母大写(默认为false):true-是,false-否。

useClearIcon:是否使用清除图标:true-当输入框值改变后,右边会显示清除的小图标。

required:标识为必填,只是做一个标识,表单提交时不会做验证。

◆Password密码输入框

密码输入框,xtype类型为passwordfield。

◆Select下拉框

下拉框组件,xtype类型为selectfield。主要的属性:

displayField:下拉框显示的字段名

valueField:下拉框值的字段名(该字段所指向的值将会被传递到后台)

options:下拉选项对象数组,对象的成员名称必须与displayField和valueField的相一致。需要注意的是当select组件设置了store属性,则本属性的值将被忽略。

store:提供给select组件下拉选项的store对象实例,通过该属性可以实现级联下拉选择。

◆DatePicker日期选择

日期选择组件,xtype类型为datepickerfield。主要的属性:

picker:用来创建日期选择器的配置对象或直接使用一个日期选择器实例。例如:

  1. picker: { 
  2.  
  3. yearFrom: 1910, //设置开始年份 
  4.  
  5. cancelButton: '取消'//设置取消按钮上的文字 
  6.  
  7. doneButton: '完成'//设置完成按钮上的文字 
  8.  
  9. slotOrder: ['year''month''day'//设置日期选择器上显示年月日的顺序 
  10.  

◆Checkbox多选框

多选框组件,xtype类型为checkboxfield。

◆Radio单选框

单选框组件,xtype类型为radiofield。

◆Email电子邮件输入框

邮件输入框组件,xtype类型为emailfield,是文本输入框组件的子类。该组件暂时没有很特别的属性。

◆Url超链接输入框

超链接输入框组件,xtype类型为urlfield,是文本输入框组件的子类。该组件暂时没有很特别的属性。

◆Slider滑动选择器

滑动选择器组件,xtype类型为sliderfield,该组件可以让用户通过手指横向滑动来选择值。主要的属性:

minValue:slider的最小值。

maxValue:slider的***值。

increment:每次滑动的增加值,只能为正整数,默认值为1。

注意:该组件的值不会传递到后台,需要手工调用该组件的getValue()方法获取设置的值,并把这个值设置到一个hidden组件中,以传递给后台程序。可以通过该组件的change事件来检测值的变化情况。

◆ Toggle开关切换器

开关切换器组件,xtype类型为togglefield,该组件是slider组件的子类,它只设置了两个值:0和1。

该组件和slider组件一样,需要手工调用getValue()方法把值设置到一个hidden组件,才能传递给后台程序。

◆Number数字输入框

数组输入框组件,xtype类型为numberfield,是文本输入框组件的子类,但只能输入数字(包括负号与小数点)。

◆Spinner微调器

微调器组件,xtype类型为spinnerfield,是number组件的子类。主要的属性:

minValue:spinner的最小值。

maxValue:spinner的***值。

incrementValue:每次点击-/+按钮时,增加的值。

cycle:循环设置项,该属性为true时,如果值已经到达maxValue设置的值,下一次点击则设置为minValue的值。同样,如果已经达到minValue设置的值,下一次点击则设置为maxValue的值。

◆Textarea文本输入域

文本输入域组件,xtype类型为textareafield,负责多行文字的输入。

◆Search搜索输入框

搜索输入框组件,xtype类型为searchfield,是文本输入框组件的子类。该组件暂时没有很特别的属性。

5.2 表单常用属性与常用方法

1) 常用属性:

  1. baseParams:Object 

发送到后台的可选参数(只有当standardSubmit属性为false时,即标准提交方式时,不会把这个属性的参数值传递到后台程序),该属性的类型为Object,例如:{‘entity.title’:’hello kitty’}。

  1. dockedItems:Object/Array 

放置到formpanel的一个或一系列组件,这些依附组件可以放置在formpanel的上下左右的位置。其典型应用是在panel上放置toolbars或tabbars,该属性的类型为一个对象或一个对象数组。

  1. standardSubmit:Boolean 

是否执行一个标准提交,默认为false(非标准提交),该属性的类型为boolean型。如果需要上传附件,则必须执行标准提交,即该属性设置为true。

  1. waitTpl: Object 

设置一个ajax提交进度的模板,例如:提交后弹出‘正在保存数据,请稍等…’的提示。

  1. record:Ext.data.Model 

该属性为只读属性,加载到form中的model实例,该属性的类型是Ext.data.Model。

2) 常用方法:

  1. getRecord(): Ext.data.Model 

该方法返回当前加载到form中的model实例。

  1. getValues(Boolean enabled): Object 

返回一个包含有全部表单元素及其值的对象,对象的属性与表单元素的name属性一致,对于具有相同name属性的checkbox或radio元素,它的值为一个值数组。参数enabled若为true则只返回哪些disabled属性为false或undefined的元素值,false则返回全部。

  1. load(Ext.data.Model instance): Ext.form.FormPanel 

把一个model实例中的数据加载到对应的form元素中(model实例中的name与form元素中name属性一致)。该方法是loadRecord方法的快捷键。通过该方法,我们可方便的把数据设置到form元素中。

  1. loadRecord(Ext.data.Model instance) : Ext.form.FormPanel 

把一个model实例中的数据加载到对应的form元素中(model实例中的name与form元素中name属性一致)。

  1. removeAll([Boolean autoDestroy]): Array 

该方法可以删除form容器中的全部组件,例如:从新增页面保存后跳转到修改页面,这时需要调用该方法把新增页面的表单及其元素全部删除,否则会出现相同名字和id的表单元素。Sencha Touch的页面跳转(setActiveItem方法),是隐藏原来的页面的元素,在该页面的***自动加上后页的html元素。

  1. reset(): Ext.form.FormPanel 

表单重设方法,把表单元素的值设置为表单元素的起始值。

  1. submit(Object options): Ext.data.Connection 

表单提交方法,如果form的standardSubmit属性为true,则执行标准提交,否则执行基于ajax方式把form数据提交到后台。该方法的参数options除非另有说明,一般包含如下的属性值:

url:String,表单提交的目标地址。

method:String,表单提交方式,一般有POST和GET。

params: String/Object,提交到后台的额外参数(即除了表单元素外的参数),如果已设置baseParams属性的话,默认是该属性值。提交时将会调用Ext.urlEncode方法对params值进行编码。

submitDisabled: Boolean,该属性值为true则提交表单中的全部元素,否则只提交disabled为false的表单元素值。

success: Function,表单提交到后台并获得后台程序响应时的回调函数,该函数包含两个参数:form(Ext.FormPanel对象)和result(服务器返回的结果对象),通过该回调函数,我们可根据后台返回的数据进行一定的逻辑处理。

failure: Function,表单提交失败时回调函数,该函数包含两个参数:form(Ext.FormPanel对象)和result(服务器返回的结果对象)。

  1. scope: Object 

回调函数的变量访问。

  1. updateRecord(Ext.data.Model instance, Boolean enabled):Ext.form.FormPanel 

把表单元素中的数据更新到model实例中。

5.3 表单数据加载

表单数据加载,可以通过load方法从一个已有的model实例中把数据设置到表单元素中,也可以通过ajax从后台获取数据,然后通过load方法加载数据到表单元素中。

1) 从model实例中加载

  1. //定义一个model 
  2.  
  3. Ext.regModel('PersonInfo', { 
  4.  
  5. fields: [ 
  6.  
  7. {name:'entity.linkman',type:'string'}, 
  8.  
  9. {name:'entity.password', type:'string'}, 
  10.  
  11. {name:'entity.sex',type:'string'}, 
  12.  
  13. {name:'entity.introduce',type:'string'
  14.  
  15.  
  16. }); 
  17.  
  18. //创建model实例数据 
  19.  
  20. var person = Ext.ModelMgr.create({ 
  21.  
  22. 'entity.linkman''hellokitty'
  23.  
  24. 'entity.password' : 'hellokitty'
  25.  
  26. 'entity.sex''m'
  27.  
  28. 'entity.introduce' : '人见人爱 车见车载' 
  29.  
  30. }, 'PersonInfo'); 
  31.  
  32. //加载数据到form元素中 
  33.  
  34. Ext.getCmp('frmInfo').load(person); 

2) 通过Ajax从后台获取数据并加载到表单中

该方式只是多了通过ajax从后台获取数据的步骤,其他的都与方式一是一样的,在此不多说了。

5.4 表单数据提交

表单数据提交有两种方式:标准提交和ajax数据提交。为了更好的增强用户的操作体验,我们一般是采取ajax提交方式,即使是附件上传功能,也可以通过提交到一个隐藏iframe方式,模拟ajax提交。

表单数据的提交通常是通过form组件的submit方法提交。

代码清单:

  1. //提交数据 
  2.  
  3. submitForm: function(sendFlag){ 
  4.  
  5. //验证数据 
  6.  
  7. if(!this.validate()){ 
  8.  
  9. return
  10.  
  11.  
  12. var_scope = this
  13.  
  14. vartipMask = '正在保存便函,请稍等...'
  15.  
  16. //是否发送标识 
  17.  
  18. Ext.getCmp('issended').setValue(sendFlag); 
  19.  
  20. if(sendFlag== '1'){ 
  21.  
  22. tipMask = '正在发送便函,请稍等...'
  23.  
  24.  
  25. //弹出正在保存的提示 
  26.  
  27. varcmpMask = Ext.getBody(); 
  28.  
  29. loadMask(cmpMask,iconPath, tipMask); 
  30.  
  31. //设置按钮失效 
  32.  
  33. vararrButton = [Ext.getCmp('btnSave'), Ext.getCmp('btnSend')]; 
  34.  
  35. enableButton(arrButton,false); 
  36.  
  37. var form= Ext.getCmp('frmInfo'); 
  38.  
  39. form.submit({ 
  40.  
  41. url: this.saveURL, 
  42.  
  43. method: 'POST'
  44.  
  45. success: function(thisForm,action){ 
  46.  
  47. unLoadMask(cmpMask); 
  48.  
  49. //实体ID 
  50.  
  51. var buId =action.result; 
  52.  
  53. varsaveTip = '成功保存便函信息!'
  54.  
  55. if(sendFlag== '1'){ 
  56.  
  57. saveTip = '成功发送便函信息!'
  58.  
  59.  
  60. var sa =Ext.Msg.alert('', saveTip); 
  61.  
  62. setTimeout(function(){ 
  63.  
  64. sa.hide(); 
  65.  
  66. enableButton(arrButton, true); 
  67.  
  68. }, 1500); 
  69.  
  70. //保存附件 
  71.  
  72. _scope.saveAttach(_scope, buId, sendFlag); 
  73.  
  74. }, 
  75.  
  76. failure: function(thisForm,action){ 
  77.  
  78. unLoadMask(cmpMask); 
  79.  
  80. enableButton(arrButton, true); 
  81.  
  82. if(action.result){ 
  83.  
  84. Ext.Msg.alert('',action.result); 
  85.  
  86. }else
  87.  
  88. Ext.Msg.alert('''提交失败,表单数据不完整!'); 
  89.  
  90.  
  91.  
  92. }); 
  93.  

若是需要上传附件,则必须使用标准提交,且需要设置form的enctype属性。该属性的设置,一般是在formpanel的afterrender监听器中设置:

  1.  
  2. xtype: 'form'
  3.  
  4. id: 'frmAttach'
  5.  
  6. margin: '0 0 0 0'
  7.  
  8. standardSubmit: true//只有标准提交(即不通过ajax方式提交),才可以上传附件 
  9.  
  10. items: [{ 
  11.  
  12. xtype: 'hiddenfield'
  13.  
  14. id: 'attRefId'
  15.  
  16. name: 'entity.id' 
  17.  
  18. },{ 
  19.  
  20. html: '<iframe id="ifrmUpload"name="ifrmUpload" style="display:none"></iframe>' 
  21.  
  22. }, this.renderAttachInfo(thisnull)], 
  23.  
  24. listeners: { 
  25.  
  26. afterrender: function(frm){ 
  27.  
  28. //设置form的属性 
  29.  
  30. Ext.getDom('frmAttach').enctype = 'multipart/form-data'
  31.  
  32. Ext.getDom('frmAttach').method = 'POST'
  33.  
  34. Ext.getDom('frmAttach').target = 'ifrmUpload'
  35.  
  36.  
  37.  
  38. }; 

第六章数据的获取

根据Sencha Touch技术框架的特点,前台展示的绝大部分数据都是通过ajax方式获取,譬如列表数据的获取、表单数据的获取等等。列表数据的获取,一般是通过store组件和list组件进行结合;表单数据的获取通常使用Ext.request方式获取。

列表数据的获取代码清单:

  1. //数据列表 
  2.  
  3. renderListData: function(){ 
  4.  
  5. //定义变量和函数的作用范围 
  6.  
  7. var _scope = this
  8.  
  9. var st = newExt.data.Store({ 
  10.  
  11. model: _scope.model, //store组件使用的Ext.data.Model 
  12.  
  13. //sorters: 'crtdt', 
  14.  
  15. autoLoad: true//是否自动加载数据 
  16.  
  17. proxy: { 
  18.  
  19. type: 'ajax'
  20.  
  21. actionMethods: 'POST'
  22.  
  23. url:_scope.url, //数据获取的url地址 
  24.  
  25. extraParams:_scope.extraParams, //请求的额外参数 
  26.  
  27. startParam:'start'
  28.  
  29. limitParam:'limit'
  30.  
  31. reader: { 
  32.  
  33. type: 'json'//reader类型-默认jsonReader, 
  34.  
  35. root: undefined,//reader root-默认undefined 
  36.  
  37.  
  38. }, 
  39.  
  40. listeners: { 
  41.  
  42. beforeload: function(st,oper){ 
  43.  
  44. oper.start = _scope.start; //设置分页起始记录 
  45.  
  46. oper.limit = _scope.limit; //设置每页显示记录数 
  47.  
  48. }, 
  49.  
  50. load: function(st,records, successful){ 
  51.  
  52. if(successful){ 
  53.  
  54. //获取后台返回的记录总数属性 
  55.  
  56. _scope.totalNum =st.getProxy().getReader().rawData.total; 
  57.  
  58. //分页按钮控制 
  59.  
  60. _scope.controlPageButtons(); 
  61.  
  62. //回调外部函数-返回结果给外部函数 
  63.  
  64. if(_scope.callbackFn){ 
  65.  
  66. _scope.callbackFn({listId:_scope.listId,total:_scope.totalNum}); 
  67.  
  68.  
  69.  
  70.  
  71.  
  72. }); 
  73.  
  74. //创建并返回list组件 
  75.  
  76. return newExt.List({ 
  77.  
  78. id: _scope.listId, 
  79.  
  80. //multiSelect: true, 
  81.  
  82. //simpleSelect: true, 
  83.  
  84. scroll: 'vertical'
  85.  
  86. store:st, //store组件对象 
  87.  
  88. emptyText: '<divstyle="margin:2px;">'+_scope.emptyText+'</div>'
  89.  
  90. loadingText: '正在获取数据'
  91.  
  92. itemTpl: _scope.itemTpl, //列表显示的模板 
  93.  
  94. listeners: { 
  95.  
  96. itemtap: function(lt, idx, item,e){ 
  97.  
  98. //点击列表记录时执行的函数 
  99.  
  100. if(_scope.itemTapFn){ 
  101.  
  102. var record =lt.getStore().getAt(idx); 
  103.  
  104. _scope.itemTapFn({listId:_scope.listId,record:record}, _scope.fnScope); 
  105.  
  106.  
  107.  
  108.  
  109. }); 
  110.  
  111.  
  112. 通过Ext.request方式获取数据的代码清单: 
  113.  
  114. //获取数据 
  115.  
  116. fetchData: function(){ 
  117.  
  118. var _scope= this
  119.  
  120. Ext.Ajax.request({ 
  121.  
  122. method: 'POST'
  123.  
  124. url: prefix + '/doc/letter/manager!fetchEditData.action'
  125.  
  126. params: { 
  127.  
  128. 'entity.id':_scope.entityId //传递给后台的参数 
  129.  
  130. }, 
  131.  
  132. success: function(response,opts){ 
  133.  
  134. varobjResp = Ext.decode(response.responseText); 
  135.  
  136. if(objResp.success){ 
  137.  
  138. varobjData = Ext.decode(objResp.result); 
  139.  
  140. //调用自定义的函数把数据设置到form中 
  141.  
  142. _scope.loadDataToForm(_scope,objData); 
  143.  
  144. }else
  145.  
  146. Ext.Msg.alert(objResp.result); 
  147.  
  148.  
  149. }, 
  150.  
  151. failure: function(response,opts){ 
  152.  
  153. Ext.Msg.alert('很抱歉,由于网络原因获取数据出错!'); 
  154.  
  155.  
  156. }); 
  157.  

第七章总结

鉴于目前移动网络的网速以及手机设备浏览器的处理能力,为了提高应用响应的速度与用户的操作体验,使用Sencha Touch开发移动应用时需要注意一些情况:

◆后台的数据传输要尽量精简,前台js书写需要尽量简洁。

◆界面要尽量精简以及少用图片,要保证应用的流畅,毕竟移动网络的网速远比不上宽带。

◆应用入口尽量要分模块,因为Sencha Touch整个应用只有一个入口的话,需要引入大量的js文件,这样可能会导致***个页面的响应速度很慢(js文件需要下载到浏览器)。

◆一些通用功能尽量组件化,提高组件的重用。

原文地址:http://blog.csdn.net/ejbcreate/article/details/7180169

责任编辑:佚名 来源: ejbcreate博客
相关推荐

2011-09-02 16:42:51

Sencha ToucWeb应用

2012-03-21 09:36:33

ibmdw

2011-09-05 10:49:14

Sencha ToucjQuery MobiHTML5

2011-09-05 13:45:25

jQuery MobiSencha Touc移动Web UI框架

2011-09-01 10:09:04

2011-09-02 15:18:49

Sencha Touc

2011-07-25 16:21:22

Sencha touc

2011-07-26 10:21:25

Sencha Touc

2011-07-26 10:44:15

Sencha Touc

2011-12-20 15:59:28

2011-09-05 11:23:26

EclipseSencha Touc框架

2011-07-26 09:41:50

Sencha Touc特性HTML 5

2010-11-22 10:31:17

Sencha touc

2011-07-25 15:55:21

Sencha ToucHtml 5

2011-09-05 10:27:02

Sencha Touc手机应用Android

2011-09-05 14:17:54

Sencha ToucMVC

2011-09-05 11:27:17

Sencha Touc框架HTML5

2012-09-06 11:25:46

IBMdw

2011-09-05 10:20:21

Sencha ToucAPP

2011-07-26 09:46:53

Sencha Touc
点赞
收藏

51CTO技术栈公众号