使用 Sencha Touch 开发超炫的跨平台移动 Web 应用(4)
 
- UID
- 1066743
|

使用 Sencha Touch 开发超炫的跨平台移动 Web 应用(4)
在定义 NestedList 组件时,有四点值得我们注意:
- 界面布局:通过 dockedItems 属性,指明了 NestedList 顶部和底部分别放置了工具栏 topbar 和 bottombar,topbar 主要用来便于用户登录和设置偏好信息,bottombar 主要是用来提供浏览博客时的一些常用操作,如订阅新的 RSS 源,删除选择的博客,刷新博客列表,给好的博文加星推荐以及回复功能。为了生成工具栏,需要生成一个 Ext.Toolbar 对象的实例,以 bottombar 为例,其代码如下:清单 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| var bottombar = new Ext.Toolbar({
dock : 'bottom',
defaults : {
ui : 'plain',
iconMask : true
},
scroll : 'horizontal',
sortable : true,
layout : {
pack : 'center'
},
items : [ {
iconCls : 'add',
handler : function(btn, event) {
addform.setCentered(true);
addform.show();
}
}, {
iconCls : 'trash'
}, {
iconCls : 'refresh'
}, {
iconCls : 'favorites'
}, {
iconCls : 'action'
} ]
});
|
该对象中主要定义了以下属性:- dock,工具栏的放置位置,可选值有 top 和 bottom;
- defaults,默认图标的 UI 效果,其中 ui 指背景颜色的样式,可选值有 dark,light 和 plain;
- scroll,滚动方向,可选值有 horizon,vertical 和 both;
- layout,表示工具栏图标的布局方式,示例中表示的是居中排列。值得注意的是该属性应该由一个 Object 对象来指定而不是 string;
- items,该属性用于指定一个数组,来表示工具栏中的图标元素的集合,每个图标对象至少需要有一个 iconCls 属性来指定其样式,而 handler 属性则用于指定处理图标点击事件的方法,该方法回调时会传入两个参数 function(btn, event),第一个指当前被触发事件的对象,第二个指被触发的事件类型,本例中通过该方法弹出一个表单窗口用于提供给用户输入感兴趣的博客 RSS 订阅源。
- 获取数据:从后台通过相关 API 获取数据并展示在 UI 组件上,是实现 Web 应用的核心问题,Sencha Touch 组件一般都是通过指定 store 数据源对象来实现的。例如在本例中,采用 Ext.data.TreeStore 对象来定义在 NestedList 中层次化数据的获取,其相关代码如下:清单 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| Ext.regModel('ListItem', {
idProperty : 'text',
fields : [ {
name : 'text',
type : 'string'
}, {
name : 'link',
type : 'string'
}, {
name : 'description',
type : 'string'
} ]
});
var store = new Ext.data.TreeStore({
model : 'ListItem',
proxy : {
type : 'ajax',
url : '/myblog/list',
reader : {
type : 'tree',
root : 'items'
}
}
});
|
首先,通过 model 属性来指明返回数据的模型,该模型是通过 Ext.regModel() 方法来建立的,主要是为了告诉程序返回数据是什么结构;其次,通过 proxy 属性来指明返回数据的获取方式,该框架中主要有两种 Proxy,Client proxy 和 Server proxy,Client Proxy 主要用于存储本地数据,其子类有三个:- LocalStorageProxy,在浏览器支持的情况下将数据保存至 localStorage;
- SessionStorageProxy,在浏览器支持的情况下将数据保存至 sessionStorage;
- MemoryProxy,将数据保存在内存中,但是当页面刷新时,数据都将会丢失。
Server proxy 主要用于存储一些通过远程请求服务器而获取的数据,它包括: - AjaxProxy,发送一个 HTTP 请求到相同域的服务器;
- ScriptTagProxy,使用 JSON-P 发送请求到不同域的服务器。
本例中采用的是最为常用的 Ajax 方式通过请求 servlet URL(/myblog/list) 来获取 JSON 数据。 - 自定义组件:使用 NestedList 时,开发者要注意的是我们需要自己实现 getDetailCard() 方法,用于定义对叶子节点数据的查看 UI 组件。非常幸运的是,Sencha Touch 框架为我们提供了良好的扩展机制用于自定义组件,这为我们构建结构清晰、面向对象的 JavaScript 程序打下了基础,示例中展示了如何扩展出一个自定义组件,代码片段如下:清单 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| Ext.ux.DescBox = Ext.extend(Ext.Component, {
...
afterRender : function() {
Ext.ux.DescBox.superclass.afterRender.apply(this, arguments);
this.description = this.getTargetEl().createChild({
tag : 'pre',
html : this.value
});
},
getValue : function() {
return this.value;
},
setValue : function(description) {
this.value = description;
if (this.rendered) {
this.description.update(this.value);
}
}
});
|
我们定义了一个博客内容描述信息展示组件 Ext.ux.DescBox,它继承自 Ext.Component 组件,并且自定义了 Get 和 Set 方法,同时重写了父类的 afterRender 方法,其中第一行的代码 Ext.ux.DescBox.superclass.afterRender.apply(this, arguments);必须调用,指的是将子类的参数应用到父类的构造方法中,类似于 Java 程序中的 super() 方法;第二行代码 this.description = this.getTargetEl().createChild(...)指在 Component 组件中创建一个 HTML 标签 pre, 并将 value 的值放置于 pre 标签中。
|
|
|
|
|
|