Extjs MVC模式

本文专为ExtJS的新手朋友制作,高手绕行。
有图有真相,最后实现的效果图如下:
Extjs MVC模式_第1张图片
案例实现的功能介绍:

1.完美应用ExtJS border布局,效果见上图;

2.实现TreePanel右键菜单,效果如下图:

Extjs MVC模式_第2张图片

3.动态更改TreePanel节点名称,效果如下:

Extjs MVC模式_第3张图片
修改后的结果如下:
Extjs MVC模式_第4张图片

4.实现ExtJS页面之间传参(详细请参看代码)

5.如何在controller中给页面添加监听事件

6.点击树形节点,切换页面

作为一个ExtJS的自学以及使用者,李坏觉得这是一个非常好的ExtJS MVC模式开发的入门级案例,用到了几乎所有的ExtJS的基础性知识。如果大家对案例有任何疑问,欢迎各位留言或加Q与李坏交流

 ExtJS是一种主要用于创建前端用户界面的ajax框架。相比于传统的WEB开发,ExtJS更适合做企业级的系统应用。ExtJS框架不但功能强大,由于其省去了不少的前端开发工作,其开发速度也是快的惊人,所以目前有很多的WEB开发者更愿意用它开发企业内部的系统。
ITLee由于工作的需要,最近也接触了一下ExtJS,用它开发了一些简单的系统应用。学习的过程中,发现很多接触ExtJS较早的人都说ExtJS3.0与ExtJS4.0有较大的区别,由于ITLee本人没用过3.0版的这里不做过多的介绍。只是简单的说一下,ExtJS4.X中最大的改变恐怕就是Ext本身的MVC模式了,由于本人天资愚钝且基础薄弱,还是费了很大劲才摸到它的门槛的。 这里给出一个小的案例,方便大家今后学习参考。
由于ITLee在实际应用中,使用 ExtJS的MVC模式确实是费了一些周折,所以本案例的主要目的是帮助大家了解一下它的MVC模式以及学会最基础的布局。废话不多说,下面来看一下案例最终的实现效果:
Extjs MVC模式_第5张图片
由上图可知,网页的布局有三部分组成:顶部标题、左侧菜单和右侧主题内容显示。这里我们对案例的布局有个初步印象,方便今后我们的进一步学习。
了解了项目的最终效果,下面来看一下该案例最终的文件结构:
Extjs MVC模式_第6张图片
有文件结构可以看出,在整个项目中,app文件夹是我们的主要工作目录,其中包含:controller(控制器)、model(数据模型)、store(数据集)、view(视图)。另外还有server文件夹,其主要目的是代替后台服务器为项目提供数据。这些内容我们将在今后的文章中逐步讲解,今天我们来看一下index.html和app.js这两个文件。
index.html文件代码:
查看源代码
打印 帮助
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
4 <metahttp-equiv="Content-Type"content="text/html; charset=utf-8">
5 <title>ExtJS学习:MVC模式案例</title>
6 <linkrel="stylesheet"type="text/css"href="../extjs/resources/css/ext-all.css"/>
7 <linkrel="stylesheet"type="text/css"href="../extjs/examples/shared/example.css"/>
8 <scripttype="text/javascript"src="../extjs/bootstrap.js"></script>
9 <scripttype="text/javascript"src="../extjs/locale/ext-lang-zh_CN.js"></script>
10 <scripttype="text/javascript"src="app.js"></script>
11 </head>
12 <body>
13 <iframeid='contentIframe'name='contentIframe'style='height:100%;width:100%'frameborder="no"></iframe>
14 </body>
15 </html>

这个文件主要的目的就是对ExtJS框架文件的引用,这里我们不做过多的介绍。
app.js文件代码:

查看源代码
打印 帮助
1 Ext.onReady(function(){
2 //开启悬浮提示功能
3 Ext.QuickTips.init();
4 //开启动态加载
5 Ext.Loader.setConfig({
6 enabled:true
7 });
8 //创建应用程序的实例
9 Ext.application({
10 //设定命名空间
11 name:'Demo',
12 //指定配置选项,设置相应的路径
13 appFolder:'app',
14 //加载控制器
15 controllers: ['demoController'],
16 //自动加载和实例化Viewport文件
17 autoCreateViewport:true
18 });
19 });

app.js文件可以看成是对我们整个项目的全局设置,其中我们需要注意的有:
(1)Ext.Loader.setConfig帮我们开启了自动加载的功能,这个功能默认是不开启的,需要我们手动开启,否则以后开发的很多文件都会找不到,报以下错误:
自动加载未开启报错信息
(2)name: ‘Demo’给项目规定了一个命名空间,它将作为一个全局变量应用于整个项目中,帮助我们识别属于本项目的应用文件。
(3)appFolder: ‘app’这个配置项,帮我们指定到app文件夹中。
至此,我们对案例已经有了一个整体的认识。下一讲我们将会详解项目的整体布局。

 在ExtJS MVC案例系列教程的第一讲中我们对案例有了一个整体的认识,了解了案例最终的效果以及最终的文件结构,简单的认识了index.html文件,详细的分析了app.js文件的作用以及文件当中的主要步骤。这篇文章是我们系列教程的第二讲,主要讲解ExtjS框架怎么使用MVC模式对代码进行布局。
到目前为止我们现有的文件只有根目录下的index.html和app.js两个文件,不具有任何的实际意义。下面我们开始着手创建我们的项目,让它能够实实在在的展现在我们的浏览器中。首先,我们在根目录下创建app文件夹,然后在app文件夹下创建controller和view两个文件夹,分别存放我们的控制器文件和视图文件。

定义ViewPort

VeiwPort代表整个浏览器显示区域,该对象渲染到页面的body区域,并会随着浏览器显示区域的大小自动改变,一个页面中只能有一个ViewPort 实例。下面我们在view文件夹中创建Viewport.js文件,然后添加如下代码:

查看源代码
打印 帮助
1 Ext.define('Demo.view.Viewport', {
2 extend:'Ext.container.Viewport',
3 //布局方式:border
4 layout:'border',
5 items: [{
6 title:'ExtJS案例',
7 collapisble:true,
8 region:'north',
9 height: 100,
10 html:'<br><center><font size=5>MVC模式实现的ExtJS案例</font><br><font size=2>源码来源:ITLee博客</font></center>'
11 },{
12 title:'功能菜单',
13 region:'west',
14 width: 180,
15 split:true,
16 collapisble:true,
17 html:'这里是菜单部分'
18 }, {
19 id:'mainContent',
20 title:'主题内容显示',
21 layout:'fit',
22 region:'center',
23 collapisble:true,
24 contentEl:'contentIframe'
25 }]
26 });

在Viewport中我们用border的布局方式将整个网页分为三个部分:头部(north)、左部(west)、主题部分(center)。

定义一个控制器

控制器是整个应用程序的关键,他负责监听事件,并对某些时间做出相应的动作。现在我们在controller文件夹下创建一个控制器,命名为demoController.js(这里的命名应该与app.js文件中加载的控制器名称相同),然后我们为该文件添加以下代码:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 //将Viewport.js添加到控制器
4 views: ['Viewport']
5 });

在控制器中我们通过views配置项,将所需视图加载到控制器中。现在我们通过浏览器就可以对项目进行查看了,查看效果如下:
Extjs MVC模式_第7张图片
至此,我们对网页的布局就算是完成了,希望对大家有所帮助。下一讲我们将讲解树形菜单的实现。

 在ExtJS MVC案例系列教程的前两讲,我们了解了该案例的最终实现效果,并且在ExtJS学习:MVC模式案例(二)中我们添加Viewport.js和demoController.js两个文件,实现了对整个网页的基本布局。这一讲使我们系列教程的第三讲,主要实现网页左侧的树形菜单部分,希望对入门级的WEB开发者提供一个引导的作用。
到目前为止,我们的文件结构如下图:
Extjs MVC模式_第8张图片
接下来,我们在view文件夹中添加一个mentTree.js文件,用来作为树形菜单组件。为该文件添加以下代码:

查看源代码
打印 帮助
1 Ext.define('Demo.view.menuTree', {
2 extend:'Ext.tree.Panel',
3 alias:'widget.menutree',
4 border:false,
5 //规定锚链接地址的显示区域
6 hrefTarget:'mainContent',
7 //是否显示根节点
8 rootVisible:false,
9 //数据集
10 store:'menuStore',
11 //菜单样式
12 bodyStyle: {
13 background:'#ffc',
14 padding:'10px'
15 }
16 });

这样我们就创建了一个菜单的组件,但是,现在我们的菜单还不能正常工作,因为菜单中还没有填充数据。ExtJS4中我们用单独的一个文件来创建数据模型和数据集,在创建数据集前我们首先创建数据模型。在app文件夹下创建model文件夹,并且在该文件夹下创建menuModel.js文件,为该文件添加以下代码:

查看源代码
打印 帮助
1 Ext.define('Demo.model.menuModel', {
2 extend:'Ext.data.Model',
3 fields:[
4 {name:'id', type:'int'},
5 {name:'pid', type:'int'},
6 {name:'text', type:'varchar'},
7 //type为布尔型时,后面的默认值是必须写的,要不会出错
8 {name:'leaf', type:'boolean', defaultValue:true},
9 {name:'url', type:'varchar'}
10 ]
11 });

有了数据模型,接下来我们创建store文件夹,以及在该文件夹下创建menuStore.js文件,添加下面的代码:

查看源代码
打印 帮助
1 Ext.define("Demo.store.menuStore",{
2 extend:'Ext.data.TreeStore',
3 defaultRoodId:'root',
4 requires:'Demo.model.menuModel',
5 model:'Demo.model.menuModel',
6 proxy:{
7 type:'ajax',
8 url:'./server/data.json',
9 reader:'json',
10 autoLoad:true
11 }
12 });

数据集和数据模型都有了,那么我们怎么给菜单添加数据呢?一般情况下,菜单所需的数据都是有后台服务器提供,因为我们这里主要讲解ExtJS的知识,尽量不去涉及后端的东西,我们可以用json格式模拟后台数据输出。现在,我们在根目录下创建server文件夹,在该文件夹下创建一个data.json的文件用来为前端提供数据:

查看源代码
打印 帮助
1 [
2 {"id":"2",
3 "pid":"1",
4 "text":"用户管理",
5 "leaf":"0",
6 "url":"http:\/\/www.lihuai.net",
7 "children":[{
8 "id":"5",
9 "pid":"2",
10 "text":"基本信息",
11 "leaf":"1",
12 "url":"http:\/\/www.sogou.com",
13 "children":""},{
14 "id":"11",
15 "pid":"2",
16 "text":"信息管理",
17 "leaf":"1",
18 "url":"http:\/\/www.sogou.com",
19 "children":""},{
20 "id":"12",
21 "pid":"2",
22 "text":"添加用户",
23 "leaf":"1",
24 "url":"http:\/\/www.sogou.com",
25 "children":""}]},
26 {"id":"3",
27 "pid":"1",
28 "text":"产品管理",
29 "leaf":"0",
30 "url":"http:\/\/www.so.com",
31 "children":[{
32 "id":"7",
33 "pid":"3",
34 "text":"产品信息",
35 "leaf":"1",
36 "url":"http:\/\/www.so.com",
37 "children":""},{
38 "id":"8",
39 "pid":"3",
40 "text":"产品添加",
41 "leaf":"1",
42 "url":"http:\/\/www.so.com",
43 "children":""}]}
44 ]

为了简单起见,每个节点的url地址我们用简单的网页替代。万事俱备,只差加载了。那么,怎么才能将我们写好的菜单组件加载到我们的项目中呢?
首先,修改我们的Viewport.js文件,将菜单组件添加到整个视图中,修改后的代码如下:

查看源代码
打印 帮助
1 Ext.define('Demo.view.Viewport', {
2 extend:'Ext.container.Viewport',
3 //布局方式
4 layout:'border',
5 items: [{
6 title:'ExtJS案例',
7 collapisble:true,
8 region:'north',
9 height: 100,
10 html:'<br><center><font size=5>MVC模式实现的ExtJS案例</font><br><font size=2>源码来源:ITLee博客</font></center>'
11 },{
12 title:'功能菜单',
13 region:'west',
14 width: 180,
15 split:true,
16 collapisble:true,
17 //这里是修改的部分
18 items:[{
19 xtype:'menutree'
20 }]
21 }, {
22 id:'mainContent',
23 title:'主题内容显示',
24 layout:'fit',
25 region:'center',
26 collapisble:true,
27 contentEl:'contentIframe'
28 }]
29 });

接下来,修改demoController.js文件,实现对菜单组件的加载,修改后的代码:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 views: ['Viewport','menuTree'],
4 stores: ['menuStore'],
5 model: ['menuModel']
6 });

现在,用浏览器查看我们的案例,左侧已经显示出菜单栏了,效果如下图:
Extjs MVC模式_第9张图片
当我们点击树形节点的时候,发现右侧主题部分并没有显示网页内容,这是因为我们还没有为节点添加监听事件的原因。具体如何添加切换页面的效果,下一讲我们将会详细讲解。

 通过ExtJS MVC案例系列教程的前三讲,我们基本实现了MVC模式布局ExtJS项目的目的,并且在浏览器中也可以看到最为常见的网页布局结构。但是,作为WEB开发者,并不是能够实现网页布局就算是完成任务了,我们还需要实现一定的功能。在这一讲中,我们将实现当点击ExtJS菜单节点的时候,网页主题部分显示相对应的内容。
到目前为止,我们的文件结构:
Extjs MVC模式_第10张图片
本讲我们不会添加新的文件,只是对原来的文件进行修改即可。前面我们说过,控制器的主要作用是监听事件,控制逻辑。所以,我们今天主要修改demoController.js这个文件,为我们的项目添加切换页面的功能。目前我们demoController.js文件的代码为:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 views: ['Viewport','menuTree'],
4 stores: ['menuStore'],
5 model: ['menuModel']
6 });

首先我们需要对menuTree组件的鼠标点击事件进行监听,修改后的代码:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 views: ['Viewport','menuTree'],
4 stores: ['menuStore'],
5 model: ['menuModel'],
6 //通过init函数来监听视图事件,控制视图与控制器的交互
7 init:function() {
8 //init函数通过this.control来负责监听
9 this.control({
10 //被监听的组件的别名
11 'menutree': {
12 //监听鼠标点击事件,点击后调用changePage方法
13 itemclick:this.changePage,
14 }
15 });
16 },
17 changePage:function(){
18 alert('success');
19 }
20 });

刷新页面,点击菜单几点,弹出success说明我们监听事件成功。下面我们继续修改changePage方法,实现对主体内容部分页面的切换功能。demoController.js代码如下:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 views: ['Viewport','menuTree'],
4 stores: ['menuStore'],
5 model: ['menuModel'],
6 //通过init函数来监听视图事件,控制视图与控制器的交互
7 init:function() {
8 //init函数通过this.control来负责监听
9 this.control({
10 //被监听的组件的别名
11 'menutree': {
12 //监听鼠标点击事件,点击后调用changePage方法
13 itemclick:this.changePage,
14 }
15 });
16 },
17 changePage:function(view, rec, item, index, e){
18 //获取url地址
19 varurl = rec.get('url');
20 //获取当前节点信息
21 vartitle = rec.get('text');
22 //将主体内容部分的url地址指定为我们获取到的url
23 Ext.getDom('contentIframe').src = url;
24 //将主体内容框的标题设置为我们获取的节点信息
25 Ext.getCmp('mainContent').setTitle(title);
26 }
27 });

通过对changePage方法的修改,刷新页面,当我们再次点击节点的时候,右侧主体内容部分将显示对应url的页面信息,大功告成。
今天我们实现了页面切换的功能,下一讲我们将讲解如何实现右键菜单。

 到目前为止,我们ExtJS MVC案例系列教程已经进行了四讲,在这四讲中我们通过ExtJS的MVC模式实现了网页的布局以及页面的切换功能。今天我们主要实现右键菜单的功能,这也是我们整个案例教程的最后一讲,由于ITLee也是ExtJS的初雪者,写这些文章对那些有过ExtJS开发经验的人来说并没有什么实际意义,主要是希望对ExtJS的初学者起到抛砖引玉的作用。
要实现右键菜单的功能,首先我们需要添加一个菜单组件,在view文件夹中新建contextMenu.js文件,该文件中添加以下代码:

查看源代码
打印 帮助
1 Ext.define('Demo.view.contextMenu', {
2 extend:'Ext.menu.Menu',
3 alias:'widget.contextmenu',
4 float:true,
5 items: [{
6 xtype:'button',
7 text:'添加',
8 action:'add',
9 iconCls:'leaf'
10 }, {
11 xtype:'button',
12 text:'删除',
13 action:'del',
14 iconCls:'leaf'
15 }, {
16 xtype:'button',
17 text:'编辑',
18 action:'edit',
19 iconCls:'leaf'
20 }]
21 });

正如我们前面所说的,添加组件后需要在控制器中进行加载,否则ExtJS的自动加载机制将不能找到我们的文件,下面修改demoController.js文件的view配置项,修改后的代码如下:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 //这次的修改在这里,给view配置项添加“contextMenu”
4 views: ['Viewport','menuTree','contextMenu'],
5 stores: ['menuStore'],
6 model: ['menuModel'],
7 //通过init函数来监听视图事件,控制视图与控制器的交互
8 init:function() {
9 //init函数通过this.control来负责监听
10 this.control({
11 //被监听的组件的别名
12 'menutree': {
13 //监听鼠标点击事件,点击后调用changePage方法
14 itemclick:this.changePage,
15 }
16 });
17 },
18 changePage:function(view, rec, item, index, e){
19 //获取url地址
20 varurl = rec.get('url');
21 //获取当前节点信息
22 vartitle = rec.get('text');
23 //将主体内容部分的url地址指定为我们获取到的url
24 Ext.getDom('contentIframe').src = url;
25 //将主体内容框的标题设置为我们获取的节点信息
26 Ext.getCmp('mainContent').setTitle(title);
27 }
28 });

做完以上工作后,接下来就是为我们的menuTree组件添加右键监听事件了,修改控制器文件demoController.js:

查看源代码
打印 帮助
1 Ext.define('Demo.controller.demoController', {
2 extend:'Ext.app.Controller',
3 views: ['Viewport','menuTree','contextMenu'],
4 stores: ['menuStore'],
5 model: ['menuModel'],
6 //通过init函数来监听视图事件,控制视图与控制器的交互
7 init:function() {
8 //init函数通过this.control来负责监听
9 this.control({
10 //被监听的组件的别名
11 'menutree': {
12 //监听鼠标点击事件,点击后调用changePage方法
13 itemclick:this.changePage,
14 //监听鼠标右键事件,点击后调用contextMenu方法
15 itemcontextmenu:this.contextMenu
16 }
17 });
18 },
19 //页面切换方法
20 changePage:function(view, rec, item, index, e){
21 //获取url地址
22 varurl = rec.get('url');
23 //获取当前节点信息
24 vartitle = rec.get('text');
25 //将主体内容部分的url地址指定为我们获取到的url
26 Ext.getDom('contentIframe').src = url;
27 //将主体内容框的标题设置为我们获取的节点信息
28 Ext.getCmp('mainContent').setTitle(title);
29 },
30 //显示右键菜单方法
31 contextMenu:function(tree, record, item, index, e, eOpts){
32 //阻止浏览器默认右键事件
33 e.preventDefault();
34 e.stopEvent();
35 //显示右键菜单
36 varview = Ext.widget('contextmenu');
37 view.showAt(e.getXY());
38 }
39
40 });

在demoController.js文件中添加以上代码后,刷新页面,在菜单节点上点击右键,看到如下效果图:
Extjs MVC模式_第11张图片
现在,我们整个案例教程就结束了,虽然还有很多功能没实现,如果继续扩展的话,怕是永远也讲不完了,呵呵,主要目的还是为ExtJS的新手们起一个引导的作用,希望对大家有所帮助。
欢迎各位浏览交流,共同进步!

 

你可能感兴趣的:(Extjs MVC模式)