sencha touch 类的使用

时间:2023-01-31 18:28:48

sencha touch 有一套自己的类机制,可以以面向对象的方式去写代码,封装业务逻辑,sencha touch 的组件、插件、api等都建立在这一套类机制的上面

在实际开发中,我们需要遵循这一套机制,以免造成不必要的麻烦。

 

所以的类都是继承于Ext.Base

定义一个类的语法:Ext.define(className, properties);

其中className是类名,properties属于配置。

 

sencha touch开发推荐使用mvc结构,在这里我推荐以下结构

sencha touch 类的使用

如图所示,我们一般在app文件夹中进行开发,其中config属于全局配置文件,是一个静态类

代码如下:

 1 //全局配置文件
 2 Ext.define('app.config', {
 3     //设置别名是为了方便调用,这样直接config.name就能获取到变量。
 4     alternateClassName: 'config',
 5     statics: {
 6         version: '1.0.0',
 7         used: {
 8             add: 'http://www.361y.cn:8080/Json/Used.asmx/Add',
 9             update: 'http://www.361y.cn:8080/Json/Used.asmx/Update',
10             destroy: 'http://www.361y.cn:8080/Json/Used.asmx/Delete',
11             list: 'http://www.361y.cn:8080/Json/Used.asmx/List',
12             one: 'http://www.361y.cn:8080/Json/Used.asmx/One'
13         }
14     }
15 });

如上所示,className的命名属于命名空间,此静态类的className是app.config,在这里表示app文件夹中的config.js文件。

为了方便调用,我们为他配置了alternateClassName属性。

我们在statics属性中配置全局变量,此类中我们只是配置了变量。

 

我们还可以在里面配置方法,不过为了方便维护,在另一个静态类中进行配置。

代码如下:

  1 //公用类
  2 Ext.define('app.util', {
  3     alternateClassName: 'util',
  4     statics: {
  5         //比较两个对象是否相等
  6         equals: function (x, y) {
  7             if (x === y) {
  8                 return true;
  9             }
 10             if (!(x instanceof Object) || !(y instanceof Object)) {
 11                 return false;
 12             }
 13             if (x.constructor !== y.constructor) {
 14                 return false;
 15             }
 16             for (var p in x) {
 17                 if (x.hasOwnProperty(p)) {
 18                     if (!y.hasOwnProperty(p)) {
 19                         return false;
 20                     }
 21                     if (x[p] === y[p]) {
 22                         continue;
 23                     }
 24                     if (typeof (x[p]) !== "object") {
 25                         return false;
 26                     }
 27                     if (!Object.equals(x[p], y[p])) {
 28                         return false;
 29                     }
 30                 }
 31             }
 32             for (p in y) {
 33                 if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) {
 34                     return false;
 35                 }
 36             }
 37             return true;
 38         },
 39         //重写ajax(需要初始化)
 40         overrideAjax: function () {
 41             var me = this;
 42             //开始加载
 43             Ext.Ajax.on('beforerequest',
 44             function (connection, options) {
 45                 if (!options.hidMessage) {
 46                     me.showMessage('正在努力加载中...');
 47                 }
 48             });
 49             //加载成功
 50             Ext.Ajax.on('requestcomplete',
 51             function (connection, options) {
 52                 me.hideMessage();
 53             });
 54             //加载失败
 55             Ext.Ajax.on('requestexception',
 56             function (connection, options) {
 57                 if (!options.hidMessage) {
 58                     me.showMessage('加载失败,请检查网络是否正常...', true);
 59                 }
 60             });
 61         },
 62         //重写list(需要初始化)
 63         overrideList: function () {
 64             //重写分页插件
 65             Ext.define("Ext.zh.plugin.ListPaging", {
 66                 override: "Ext.plugin.ListPaging",
 67                 config: {
 68                     //自动加载
 69                     autoPaging: true,
 70                     //滚动到最底部时是否自动加载下一页数据
 71                     noMoreRecordsText: '没有更多内容了',
 72                     loadMoreText: '加载更多...' //加载更多按钮显示内容
 73                 }
 74             });
 75             //重写下拉刷新
 76             Ext.define("Ext.zh.plugin.PullRefresh", {
 77                 override: "Ext.plugin.PullRefresh",
 78                 config: {
 79                     lastUpdatedText: '上次刷新时间:',
 80                     loadedText: '等一会再刷新吧...',
 81                     loadingText: '加载中...',
 82                     pullText: '下拉可以手动刷新',
 83                     releaseText: '松开可以刷新',
 84                     lastUpdatedDateFormat: 'Y-m-d H:i'
 85                 }
 86             });
 87             //重写List
 88             Ext.define("Ext.zh.List", {
 89                 override: "Ext.List",
 90                 config: {
 91                     //取消选择效果
 92                     selectedCls: '',
 93                     //禁用加载遮罩,防止跳转时页面卡顿,使用统一的遮罩效果
 94                     loadingText: false,
 95                     cls: 'list',
 96                     deferEmptyText: false,
 97                     emptyText: '没有更多内容了'
 98                 }
 99             });
100         },
101         //重写Pick相关(需要初始化)
102         overridePick: function () {
103             Ext.Date.monthNames = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"];
104             Ext.define("Ext.zh.DatePicker", {
105                 override: "Ext.picker.Date",
106                 config: {
107                     yearFrom: 2000,
108                     monthText: '月',
109                     dayText: '日',
110                     yearText: '年'
111                 }
112             });
113             Ext.define("Ext.local_zh_cn.Picker", {
114                 override: "Ext.picker.Picker",
115                 applyDoneButton: function (config) {
116                     if (config) {
117                         if (Ext.isBoolean(config)) {
118                             config = {};
119                         }
120                         if (typeof config == "string") {
121                             config = {
122                                 text: config
123                             };
124                         }
125                         Ext.applyIf(config, {
126                             ui: 'action',
127                             align: 'right',
128                             text: '确定'
129                         });
130                     }
131                     return Ext.factory(config, 'Ext.Button', this.getDoneButton());
132                 },
133                 applyCancelButton: function (config) {
134                     if (config) {
135                         if (Ext.isBoolean(config)) {
136                             config = {};
137                         }
138                         if (typeof config == "string") {
139                             config = {
140                                 text: config
141                             };
142                         }
143                         Ext.applyIf(config, {
144                             align: 'left',
145                             text: '取消'
146                         });
147                     }
148                     return Ext.factory(config, 'Ext.Button', this.getCancelButton());
149                 }
150 
151             });
152         },
153         //app初始化执行
154         inIt: function () {
155             this.overrideList();
156             this.overrideAjax();
157             this.addMessage();
158             this.overridePick();
159         }
160     }
161 });

如此我们可以通过util.equals('a','b')调用指定方法,另外我们可以通过this来进行内部调用

 

以上两个类不会自动创建,我们必须创建之后才能调用。一般我们在app.js中进行创建

代码如下:

 1 Ext.application({
 2     name: 'app',
 3     requires: ['app.config','app.util', 'Ext.MessageBox'],
 4     controllers: ['Main', 'Used', 'User', 'Job'],
 5     launch: function () {
 6         // Destroy the #appLoadingIndicator element
 7         Ext.fly('appLoadingIndicator').destroy();
 8         util.inIt();
 9         // Initialize the main view
10         Ext.Viewport.add(Ext.create('app.view.Main'));
11     }
12 });

在此代码中我们通过requires进行了创建。

值得注意的是,全局变量,公共方法不止以上一种写法,你可以自行尝试一下其他写法。

 

下面来说一说普通类,例如一个视图。

代码如下:

 1 Ext.define('app.view.About', {
 2     alternateClassName: 'about',
 3     extend: 'Ext.Container',
 4     xtype: 'about',
 5     requires: ['ux.plugin.ConHref'],
 6     config: {
 7         title: '关于我们',
 8         margin: 10,
 9         plugins: 'conHref',
10         html: '<p>“抛砖网”国内首家首创纯实战型培训机构,提供在线培训、技术指导及答疑!</p><br/><p>团队通过360全方位技术培训+1度手把手技术指导,保证每一个学员能最快掌握实际工作技能;</p><br/><p>让每一个学员都能站在我们的肩膀上,展翅高飞。赶快关注“抛砖网”。</p><br/><p>网址:<a href="http://www.361y.cn">www.361y.cn</a></p><p>QQ群:263271569</p><p>官方微信号:paozhuanedu</p><br/><p><strong>本期课程说明及付费链接:</strong></p><p><a href="http://item.taobao.com/item.htm?id=36768998716">item.taobao.com/item.htm?id=36768998716</a></p>'
11     }
12 });

 

这是一个视图类,所在路径为app/view/About.js

在这里设置alternateClassName是为了方便创建,我们可以通过Ext.create('about')来创建类,等同于Ext.create('app.view.About')

extend属性表示他继承于Ext.Container这个类。

xtype是为了方便在控制层中进行监听,通常此属性是必须的。

requires表示这个类所依赖的类,在这里是指一个插件。通过config.plugins来使用

config表示此类中的各种配置,框架自动帮每一个配置项添加了以下方法:

getter方法 - 如getName就是返回name的当前值。

setter方法 - 如getName就是为name设置一个新值。

getter和setter都是自动生成的,建议大家使用它们来存取类里面的数据。ST的每一个组件都使用了getter和setter的模式,这意味着如果我们知道一个配置项,也就知道如何获取和设置它的值了。

这也让你的的代码更整洁。

如果你需要在视图创建时就添加一个按钮,并且能够动态更新。

可以如下:

 1 /**
 2 * 基于Ext.navigation.Bar
 3 * 去除动画切换等功能
 4 * 可以灵活的在NavigationView子项中配置属性
 5 * 小写开头表示这是私有控件,不能直接使用
 6 */
 7 Ext.define('ux.navigationBar', {
 8     extend: 'Ext.TitleBar',
 9     requires: [
10         'Ext.Button',
11         'Ext.Spacer'
12     ],
13     config: {
14         /*导航栏标题*/
15         title: null,
16         /*item默认类型*/
17         defaultType: 'button',
18         layout: {
19             type: 'hbox'
20         },
21         /*返回按钮*/
22         backButton: {
23             align: 'left',
24             ui: 'back',
25             hidden: true
26         }
27     },
28     /*初始化配置*/
29     constructor: function (config) {
30         config = config || {};
31         if (!config.items) {
32             config.items = [];
33         }
34         this.callParent([config]);
35     },
36     /*创建返回按钮*/
37     applyBackButton: function (config) {
38         return Ext.factory(config, Ext.Button, this.getBackButton());
39     },
40     /*更新返回按钮*/
41     updateBackButton: function (newBackButton, oldBackButton) {
42         if (oldBackButton) {
43             this.remove(oldBackButton);
44         }
45         if (newBackButton) {
46             this.add(newBackButton);
47 
48             newBackButton.on({
49                 scope: this,
50                 tap: this.onBackButtonTap
51             });
52         }
53     },
54     /*点击返回按钮时触发*/
55     onBackButtonTap: function () {
56         this.fireEvent('back', this);
57     }
58 });

如上,applyBackButton方法在视图创建时会自动调用,只有返回的值部位false,并且不等于旧的值,就会自动触发updateBackButton方法,我们可以在里面进行逻辑处理。

 

另外一个类还值得主要的属性有:

alias :类似于alternateClassName,但是它的值只能是string数组

inheritableStatics:可继承的静态方法列表

mixins :额外需要继承的类

platformConfig:特殊平台或者主题中的默认配置

singleton:是否单例模式

uses :不一定依赖的类