Sencha Touch 2 快速入门系列(八) -- 控制器(Controller)

本文已添加至Sencha Touch 2快速入门系列索引:http://blog.csdn.net/ardy_c/article/details/7544470

转载请注明出处:http://blog.csdn.net/ardy_c/article/details/8543598

http://blog.csdn.net/ardy_c/article/details/8543598

控制器(Controller)

在Application中,控制器 (Controller) 负责监听用户的点击、滑动屏幕或其它等这些事件的发生,并调用相应的model来进行响应。例如,你的app中有一个登出按钮。控制器就是监听这个按钮的点击事件,并调用相应的方法对点击事件进行响应。当视图类 (View Class) 负责处理数据的显示、模型类 (Model Class) 负责处理加载和保存数据的时候,控制器类 (Controller Class) 就如粘合剂一样将视图和模型粘在一起。


与 Ext.app.Application的关系

控制器存在于Application的上下文中。一个Application通常由多个控制器构成,每一个控制器负责操作app指定的一部分。例如,一个负责处理网上购物订单的应用,可能有处理以下三种内容的控制器:订单、客户和产品。

如何使用控制器?Application使用的全部控制器都是通过在其config 属性中指定的。Application 会自动为其初始化并进行关联,所以在大部分情况下,你无需直接去初始化控制器。按照惯例,控制器的命名规则是使用它所管理的实体(通常是模型)的复数进行命名。例如,如果你的app叫作'MyApp',而你有一个控制器是管理产品 (Products) 的,惯例是创建一个 MyApp.controller.Products 类,并放在 app/controller/Products.js 路径中(路径信息可参与第一节中所展示的,sencha touch 2会将MyApp 定位到 app 目录下,而类名中的 controller.Products,会定位到 controller/Products.js 这个文件)。


在启动中

在 Application 启动的过程中,有四个主要的步骤,其中两个是属于控制器的。第一个,每一个控制器都可以定义一个初始化函数,该函数将会在调用 Application 启动函数前被调用。第二个,在 Application 和 Profile(配置,这里的profile是指device profile,用于为不同设备配置不同的响应视图) 的启动函数被调用后,作为启动过程的最后一个步骤,控制器的启动函数将会被调用。顺序如下:

1. 控制器 -- 调用控制器的初始化函数;

2. Profile -- 调用Profile的启动函数;

3. Application -- 调用Application的启动函数;

4. Controller -- 调用控制器的启动函数。

大多数情况下,你只需要将你的控制器指定的启动逻辑放到启动函数就可以了。因为控制器的启动函数将会在Application和Profile启动函数已被执行后再调用,你的app的界面初始化也将在这个时间点上进行。如果你需要在app启动前对控制器进行一些指定的处理,你可以实现控制器的初始化函数(init function)。


Refs和Control(配置属性)

控制器的中心就是一对配置属性:refs 和 control。他们被用于获取到app内部组件的关联,以及响应这些组件所产生的事件。以下我们先来看看refs配置属性。


Refs

Refs 依靠强大的 ComponentQuery 语法,可以很容易地定位到我们页面中的组件。在每一个控制器中,我们可以根据自身的需求定义refs的数量。例如,在下面的例子中,我们定义了一个 ref 叫 'nav' ,用于查找页面中一个 ID 为 ‘mainNav’ 的组件。然后,我们在后面的 addLogoutButton 函数中使用这个 refs 。请看下面的例子:

[javascript]  view plain copy
  1. Ext.define('MyApp.controller.Main', {  
  2.     extend: 'Ext.app.Controller',  
  3.   
  4.     config: {  
  5.         refs: {  
  6.             nav: '#mainNav'  
  7.         }  
  8.     },  
  9.   
  10.     addLogoutButton: function() {  
  11.         this.getNav().add({  
  12.             text: 'Logout'  
  13.         });  
  14.     }  
  15. });  

如平常一样,一个 ref 就是一对 key / value -- key (在这个例子中就是 nav) 就是这个新创建的引用的名字,value (在这个例子里就是 ‘#mainNav’) 是将被 ComponentQuery 用于查找组件。

我们创建了一个 addLogoutButton 函数,在这个函数里面通过调用getNav 函数调用了 ref。getNav这个getter函数从哪里来的?它是sencha touch 基本你定义的 refs 名称(也就是那个 key 值)自动生成的,并且保持同样的格式:以 get 开头,紧随大写字母开头的 refs 名称,这里就是 Nav 。在这个例子里面,我们看待 nav 是引用一条工具栏,我们在工具栏里面添加了一个Logout 按钮。 那么,这个 ref 将被认为是一个工具栏,请看以下代码:

[javascript]  view plain copy
  1. Ext.create('Ext.Toolbar', {  
  2.     id: 'mainNav',  
  3.   
  4.     items: [  
  5.         {  
  6.             text: 'Some Button'  
  7.         }  
  8.     ]  
  9. });  

假设在我们运行 addLogoutButton 函数前这个工具栏就已经被创建,那么在运行 addLogoutButton 函数后,它将被多加一个 Logout 按钮。


高级Refs

Refs 可以设置更多的选项,不仅有名称和选择器。这些选择是 autoCreate 和 xtype,它们大多都是一起被用到的:

[javascript]  view plain copy
  1. Ext.define('MyApp.controller.Main', {  
  2.     extend: 'Ext.app.Controller',  
  3.   
  4.     config: {  
  5.         refs: {  
  6.             nav: '#mainNav',  
  7.   
  8.             infoPanel: {  
  9.                 selector: 'tabpanel panel[name=fish] infopanel',  
  10.                 xtype: 'infopanel',  
  11.                 autoCreate: true  
  12.             }  
  13.         }  
  14.     }  
  15. });  

我们为Controller 添加了第二个 ref 。同样,名称就是 key,这里是 infoPanel, 但是,这次我们传入一个对象作为 value。 这次我们使用了一个更复杂的选择器进行查询。想象一下,你的 app 包含一个 tab panel ,并且其中一个子项(item) 名称是 fish。那么,上面设定的选择器就会在这个 ‘fish’ panel 的中匹配任何 xtype 为 infopanel 的子元素(items)。

这里不同的是,如果 infopanel 不存在于 'fish' panel 中,当在 Controller 中运行 this.getInfoPanel 的时候,它将会被自动创建。为什么它能够被自己创建? 因为我们为它指定了 xtype,在选择器没有查找到对象的时候,Controller 会自动为我们创建一个 infopanl 对象。


Control

与 refs 配置属性相关的就是 control. control 的意思就是让你的Controller 监听app里面的组件所触发的事件,并调用一些方法对这些事件进行响应。control的属性可配置成 ComponetQuery 选择器或者 refs 作为它的 keys,而事件处理函数名称字符串作为 values。请看以下例子:

[javascript]  view plain copy
  1. Ext.define('MyApp.controller.Main', {  
  2.     extend: 'Ext.app.Controller',  
  3.   
  4.     config: {  
  5.         control: {  
  6.             loginButton: {  
  7.                 tap: 'doLogin'  
  8.             },  
  9.             'button[action=logout]': {  
  10.                 tap: 'doLogout'  
  11.             }  
  12.         },  
  13.   
  14.         refs: {  
  15.             loginButton: 'button[action=login]'  
  16.         }  
  17.     },  
  18.   
  19.     doLogin: function() {  
  20.         // 当login button 被点击后调用  
  21.     },  
  22.   
  23.     doLogout: function() {  
  24.         // 任何action=logout 的button被点击后调用  
  25.     }  
  26. });  

在上面的例子中,我们声明了两个 control :一个是 loginButton ref,另一个是任何action 值为 logout 的 button。每个一声明,我们都为其传入一个事件处理器: 每一个点击事件监听,我们都为其指定一个方法(处理器),当点击事件被触发时就会被调用到。请注意,我们这里指定的两个 'doLogin' 和 'doLogout' 方法都是以函数名称的字符串形式存在于 control  的代码块内。


Routes (路由,路径集)

在 Sencha touch 2 中,可以设定routes属性,让控制器引领至 app 的任何位置。

例如,假定我们有一个控制器负责响应登陆请求和查看用户配置信息请求,并想通过 urls 来访问这些页面。我们可以根据以下方式来实现:

[javascript]  view plain copy
  1. Ext.define('MyApp.controller.Users', {  
  2.     extend: 'Ext.app.Controller',  
  3.   
  4.     config: {  
  5.         routes: {  
  6.             'login''showLogin',  
  7.             'user/:id''showUserById'  
  8.         },  
  9.   
  10.         refs: {  
  11.             main: '#mainTabPanel'  
  12.         }  
  13.     },  
  14.   
  15.     // 使用 'main' ref 来在主 TabPanel 上添加一个 loginpanel(注意, 'loginpanel' 是为这个 app 自定义的 xtype)  
  16.     showLogin: function() {  
  17.         this.getMain().add({  
  18.             xtype: 'loginpanel'  
  19.         });  
  20.     },  
  21.   
  22.     // 加载用户信息并添加一个 'userprofile' view 到主 TabPanel  
  23.     showUserById: function(id) {  
  24.         MyApp.model.User.load(id, {  
  25.             scope: this,  
  26.             success: function(user) {  
  27.                 this.getMain().add({  
  28.                     xtype: 'userprofile',  
  29.                     user: user  
  30.                 });  
  31.             }  
  32.         });  
  33.     }  
  34. });  

上面例子中,routes 属性预先设定了浏览器地址和控制器功能的映射,当路径与某一个路径 (route) 匹配时,相应的功能将被调用。routes 可以是简单的文本内容,例如 route 'login' 匹配以下 url: http://myapp.com/#login 。或者可以包含通配符,正如 route  'user/:id’,匹配以下 url:http://myapp.com/#user/123. 即使路径改变,控制器仍会自动用指定的功能。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值