Extjs4 API文档阅读(二)——MVC构架(上)

来源:互联网 发布:sql server 注释 编辑:程序博客网 时间:2024/06/10 20:11

一直想写一些Extjs4 MVC的东西,但由于自己的英文水平足够媲美小学5年纪的学生,所以在找了一些比我强一点的网友+机器翻译,总结出了以下这篇文章。但个人强烈建议去看英文原版(点击进入)。看完本文后,如有任何错误,欢迎来信或者留言指正(QQ:301109552)。

那么,我们开始吧!

对于Extjs来说,大客户端程序一直很难写,当你为大客户端程序添加更多的功能和项目的时候,项目的体积往往迅速增长。这样的大客户端程序很难组织和维持 ,所以,Extjs4配备了一个新的应用程序体系结构,它能结构化你的代码,那就是Extjs4 MVC。

Extjs4 MVC有别于其他MVC架构,Extjs有他自己定义:

1、Model是一个Field以及他的Data的集合,Modes知道如何通过Stores来表示数据,以能用于网格和其他组件。模型的工作很像Extjs3的记录集(Record class),通常通过数据加载器(Stores)渲染至网格(grid)和其他组件上边。

2、View:用以装载任何类型的组件—grid、tree和panel等等。

3、Controller—用来放使得app工作的代码,例如 render views , instantiating Models 或者其他应用逻辑。

本篇文章,我们将创建一个非常简单的应用程序,即用户数据管理,最后,你就会知道如何利用Extjs4 MVC去创建简单应用程序。Extjs4 MVC应用程序架构提供应用程序的结构性和一致性。这样的模式带来了一些重要的好处:

1、 每个应用程序的工作方式相同,我们只需要学习一次。

2、 应用程序之间的代码共享很容易,应为他们所有的工作方式都相同

3、 你可以使用EXTJS提供的构建工具创建你应用程序的优化版本。

既然是介绍Extjs4 MVC,那么,我们开始创建这个应用。

一、文件结构(File Structure): 

Extjs4 MVC的应用程序和别的应用程序一样都遵循一个统一的目录结构。在MVC布局中,所有的类放在应用程序文件夹,它的子文件夹中包含您的命名空间,模型,视图,控制器和存储器。下面来通过简单的例子来看下怎样应用。

在这个例子中,我们将整个应用程序放到一个名为”account_manager”的文件夹下,”account_manager”文件夹中的结构如上图。现在编辑index.html,内容如下:
 

<html><head>    <title>Account Manager</title>    <link rel="stylesheet" type="text/css" href="ext-4.0/resources/css/ext-all.css">    <script type="text/javascript" src="ext-4.0/ext-debug.js"></script>    <script type="text/javascript" src="app.js"></script></head><body></body></html>

二、创建app.js文件。

所有Extjs4 MVC应用从Ext.application的一个实例开始,应用程序中应包含全局设置、以及应用程序所使用的模型(model),视图(view)和控制器(controllers),一个应用程序还应该包含一个发射功能(launch function)。

现在来创建一个简单的账户管理应用。首先,需要选择一个命名空间(所有extjs4应用应该使用一个单一的全局变来来作为命名空间)。暂时,使用”AM”来作为命名空间。

 
Ext.application({    name: 'AM',    appFolder: 'app',    launch: function() {        Ext.create('Ext.container.Viewport', {            layout: 'fit',            items: [                {                    xtype: 'panel',                    title: 'Users',                    html : 'List of users will go here'                }            ]        });    }});

以上代码,做了如下几件事。首先,调用Ext.application创建一个应用程序类的实例,设置了一个”AM”的命名空间,他将作为整个应用的全局变量,也将作为Ext.Loader的命名空间,然后通过appFolder来指定配置选项设置相应的路径。最后,创建了一个简单的发射功能,这里仅仅创建了一个Viewport,其中包含一个panel,使其充满整个窗口。

 

三、定义一个控制器

控制器是整个应用程序的关键,他负责监听事件,并对某些时间做出相应的动作。现在我们创建一个控制器,将其命名为Users.js,其路径是app/controller/Users.js。然后,我们为Users.js添加如下代码:

  
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    init: function() {        console.log('Initialized Users! This happens before the Application launch function is called');    }});

完成之后,我们将创建好的控制器添加到程序配置文件:app.js中:

 
Ext.application({    ...    controllers: [        'Users'    ],    ...});

 

当我们访问index.html时,用户控制器(Users.js)自动加载,因为我们在上面的app.js中的定义中指定了。Init函数一个最棒的地方是控制器与视图的交互,这里的交互是指控制功能,因为他很容易就可以监听到视图类的事件处理函数,并采取相应的措施,并及时渲染相关信息到面板上来。

编写Users.js:

 
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    init: function() {        this.control({            'viewport > panel': {                render: this.onPanelRendered            }        });    },    onPanelRendered: function() {        console.log('The panel was rendered');    }});

在Users.js中,init函数使用this.control来负责监听,由于使用了新的ComponentQuery引擎,所以可以快速方便的找到页面上组件的引用(viewport > panel),这有些类似CSS选择器,通过匹配,快速的找到相匹配的组件。

在上面的init函数中,我们使用viewport > panel,来找到app.js中Viewport下的panel组件,然后,我们提供了一个对象的处理函数(this. onPanelRendered,注意,这里的对象是this,他的处理函数是onPanelRendered)。整个效果是,只要符合触发render事件的任何组件,那么onPanelRendered函数将被调用。当运行我们的应用程序,我们将看到以下内容。

 

四、定义一个视图

到目前为止,应用程序只有几行,也只有两个文件,app.js和app/controller/Users.js。现在我们来增加一个grid,来显示整个系统中的所有用户。作为视图组件的一个子类,我们创建一个新的文件,并把他放到app/view/user目录下。命名为List.js。整个路径是这样的。app/view/user/List.js,下面,我们写List.js的代码: 


Ext.define('AM.view.user.List' ,{    extend: 'Ext.grid.Panel',     alias : 'widget.userlist',     title : 'All Users',     initComponent: function() {        this.store = {             fields: ['name', 'email'],            data  : [                 {name: 'Ed',    email: 'ed@sencha.com'},                 {name: 'Tommy', email: 'tommy@sencha.com'}            ]         };        this.columns = [             {header: 'Name',  dataIndex: 'name',  flex: 1},             {header: 'Email', dataIndex: 'email', flex: 1}        ];         this.callParent(arguments);    }});

我们创建好的这个类,只是一个非常普通的类,并没有任何意义,为了能让我们更好的使用这个定义好的类,所以我们使用alias来定义一个别名,这个时候,我们的类可以使用Ext.create()和Ext.widget()创建,在其他组件的子组件中,也可以使用xtype来创建。

Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    views: [         'user.List'    ],    init: ...    onPanelRendered: ...});

 

修改Users.js,增加views属性,修改app.js中的launch方法,将List渲染到Viewport。

Ext.application({    ...    launch: function() {         Ext.create('Ext.container.Viewport', {            layout: 'fit',             items: {                xtype: 'userlist'            }        }); }});

看到这里,也许会有人开始抓狂了,这个user.List到底是怎么来的,为什么要这样写?如果你开始感到疑惑,那么不妨看看Ext.Loader是如何工作的(传送门),在看过Ext.Loader之后,你就会明白了,User.List就是app/view/user下的List.js文件。为什么Ext要从view下找呢?因为我们在控制器中定了views: ['user.List']。这就是Extjs动态加载的强大之处,具体Ext.Loader,请看本站的其他文章,你就会明白了。当我们刷新页面。

未完待续…