Controller ---控制器
控制器负责响应App中出现的事件。如果用户点击了你App中的登录按钮,负责监听该按钮点击事件的控制器就会执行相应的登录操作。View类负责处理数据的展示,Model类负责处理数据的加载与保存,那么Controller类就是讲Views与Models结合在一块的胶水。
Relation to Ext.app.Application ---控制器与Ext.app.Application的关系
Controller存在于Application上下文环境中。App通常有大量的Controllers组成,它们中的每一个负责处理App中一个特定的部分功能。例如:一个负责处理在线购物网站订单的App可能会有Orders,Customers和Products这些控制器。App使用的所有Controller均指定在App的Controller配置文件中。App负责Controller的实例化并保持对他们的引用,因此大多数情况下,开发者不需要直接初始化Controllers。约定俗成,控制器通常在它管理的entity(usually the Model)之后被命名,通常是复数形式--例如:你的App是‘MyApp’并且你有一个负责管理Products的Controller,通常会在app/controller/Products.js文件中创建一个MyApp.controller.Products类。Launching --启动
App启动过程有4个主要阶段,其中2个涉及到了Controller。首先,每个Controller都能定义一个 init 函数,它会在app启动之前被调用。其次,在Application 和 Profile 的 launch 函数被调用之后,作为启动过程的最后一个阶段,Controller的 launch 函数会被调用,具体过程如下:
1. Controller#init functions called
2. Profile#launch function called
3. Application#launch function called
4. Controller#launch functions called
大多数时候,你特定控制器的启动逻辑应该写在你控制器的 launch 函数中。这是因为控制器的 launch 函数在 Application 和 Profile 的 launch 函数之后被调用,你App的初始化UI在这时会期待被展示。如果你需要在App启动之前具体的控制处理,你可以实现Controller的 init 函数。
Refs and Control
Controller的核心是 refs 和 control 两个相似的配置。他们通常被容于获取App中组件的引用,根据这些组件触发的事件执行相应的操作,在下面的部分我们先来看下 refs 配置
Refs
Refs 的优势在于强大的组件查询语法很容易定位页面上的组件。对于每个控制器,我们可以根据需要定义尽可能多的 refs ,例如,在下面的例子中,我们定义了一个名为
“nav”的 ref ,用于查找页面上id 为“mainNav” 的组件。然后我们在随后的 addLogoutButton 函数中使用了那个 refs,正如本例所示:
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
nav: '#mainNav'
}
},
addLogoutButton: function() {
this.getNav().add({
text: 'Logout'
});
}
});
通常,一个 ref 仅仅就是一个键值对 -- 键(在这个案例中是‘nav’)是 生成的引用的名字, 然而 值(在本案例中是‘#mainNav’)是用于查找组件的组件选择器。
接下来我们创建了 addLogoutButton 函数,在函数中通过 它本身生成的 ‘getNav’ 函数使用了这个ref。这个getter 方法是根据你定义的refs自动生成的,遵循相同的格式--‘get’,
后面是首字母大写的ref名字。在这个案例中我们将nav的引用看做Toolbar,当我们的方法被调用的时候给他添加一个 Logout 按钮。正如所展示的,这个ref 将被识别为Toolbar。
Ext.create('Ext.Toolbar', {
id: 'mainNav',
items: [
{
text: 'Some Button'
}
]
});
假设在我们运行 ‘addLogoutButton’方法时(稍后我们将看到这个方法是如何被访问的)这个Toolbar已经被创建,它将获得添加到它上边的第二个按钮。
Advanced Refs ---高级Refs
Refs也可以传递附加可选项,除了name 和 selector。这些可选项是 autoCreate 和 xtype,这两个几乎总是一起被使用。Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
nav: '#mainNav',
infoPanel: {
selector: 'tabpanel panel[name=fish] infopanel',
xtype: 'infopanel',
autoCreate: true
}
}
}
});
我们已经给我们的Controller添加了第二个ref。名字是键,在这个例子中是‘infoPanel’,但是这次我们传递了一个对象作为值。这次我们使用了一个更加复杂的查询选择器-
-想象下你的App包含一个 tab panel,并且在tab panel 中有一个panel name为‘fish’。上面指定的选择器匹配在tab panel中panel名为‘fish’中 xtype为‘infopanel’的所有组件。
这里的区别在于,如果在‘fish’ panel中不存在infopanel,当你在你的控制器中调用this.getInfoPanel方法时,infopanel会被自动创建。Controller能够创建爱你infopanel是因为我们提供了xtype用于实例化它,以防选择器返回空值。
Control
与refs相关的配置就是 control。Control 的意思就是由控制器去监听app 组件在触发了事件并且以某种方式进行响应。Control 配置接受组件查询选择器 和 refs 作为它本身的key,监听对象最为它的值,如下所示:Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
control: {
loginButton: {
tap: 'doLogin'
},
'button[action=logout]': {
tap: 'doLogout'
}
},
refs: {
loginButton: 'button[action=login]'
}
},
doLogin: function() {
// called whenever the Login button is tapped
},
doLogout: function() {
// called whenever any Button with action=logout is tapped
}
});
在上例中,我们创建了2个control 声明-- 一个是为loginButton ref,另一个是为action=logout的所有按钮。对于每个声明,我们传递一个单独的事件处理器--两种情况都监听tap 事件--并指定了当按钮触发了tap事件时特定的操作会被调用。
注意:我们在control 块中以字符串的形式指定‘doLogin’ 和 ‘doLogout’方法--这是很重要的。