`

[ExtJS] MVC应用架构示例

阅读更多
1
项目目录结构



2.
app.js
Ext.Loader.setConfig({
			enabled : true,
			paths : {
				'Ext' : 'extjs',
				'App' : 'app',
				'Ext.ux' : 'extjs/ux'
			}
		});

Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';

Ext.require('Ext.container.Viewport');

Ext.application({
			name : 'App',
			appFolder : 'app',
			controllers : ['poll'],
			launch : function() {
				Ext.create('Ext.container.Viewport', {
							layout : 'fit',
							items : [{
                                        xtype : 'poll'
                                    }]
						});
			}
});




3.
控制器 poll.js
Ext.define('App.controller.poll', {
	extend : 'Ext.app.Controller',
	views : ['poll', 'pollQuery', 'pollList', 'pollEdit', 'pollAdd'],
    stores : ['poll'],
    models : ['poll'],
	init : function() {
		this.control({
			'pollQuery' : {
				'beforerender' : function() {
					var view = Ext.ComponentQuery.query('pollQuery')[0];
					view.loadView();
				}
			},
            
            'pollQuery form button[action=submit]' : {
                'click' : function() {
                    var formCmp = Ext.ComponentQuery.query('pollQuery form')[0];
                    var basicForm = formCmp.getForm();
	                if (basicForm.isValid()) {
                         Ext.Msg.alert("信息", "模糊查询所有文本字段.");
	                }
                }
            },
            
            'pollQuery form button[action=reset]' : {
                'click' : function() {
                    var formCmp = Ext.ComponentQuery.query('pollQuery form')[0];
                    var basicForm = formCmp.getForm();
                    basicForm.reset();
                }
            },
            
            'pollQuery form button[action=submit2]' : {
                'click' : function() {
                    var formCmp = Ext.ComponentQuery.query('pollQuery form')[1];
                    var basicForm = formCmp.getForm();
                    if (basicForm.isValid()) {
                        Ext.Msg.alert("信息", "模糊查询所有文本字段.");
                    }
                }
            },
            
            'pollQuery form button[action=reset2]' : {
                'click' : function() {
                    var formCmp = Ext.ComponentQuery.query('pollQuery form')[1];
                    var basicForm = formCmp.getForm();
                    basicForm.reset();
                }
            },

			'pollList' : {
				'beforerender' : function() {
					var view = Ext.ComponentQuery.query('pollList')[0];
					view.loadView();
				}
			},

			'pollList > grid' : {
				'itemdblclick' : function(table, record, html, row, event, opt) {
					var view = Ext.widget('pollEdit');
					view.loadView();
					view.show();
					view.down('form').loadRecord(record);
				}
			},
            
            'pollList > grid button[action=add]' : {
                'click' : function() {
                    var view = Ext.widget('pollAdd');
                    view.loadView();
                    view.show();
                }
            },
            
            'pollList > grid button[action=remove]' : {
                'click' : function() {
                    var grid = Ext.ComponentQuery.query('pollList > grid')[0];
                    var sm = grid.getSelectionModel();
                    grid.store.remove(sm.getSelection());
                    
                    // 提交后台
                }
            },

			'pollEdit button[action=save]' : {
				'click' : function(button, event, opt) {
					var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues();
					record.set(values);
					win.close();
					this.getPollStore().sync();
                    
                    // 提交后台
				}
			},
            
            'pollEdit button[action=close]' : {
                'click' : function(button, event, opt) {
                    var win = button.up('window');
                    win.close();
                }
            },
            
            'pollAdd button[action=save]' : {
                'click' : function(button, event, opt) {
                    var win = button.up('window'), form = win.down('form'), values = form.getValues();
                    win.close();
                    var grid = Ext.ComponentQuery.query('pollList > grid')[0];
                    var store = grid.store;
                    var record = Ext.create('App.model.poll', values);
                    store.add([record]);
                    
                    // 提交后台.
                }
            },
            
            'pollAdd button[action=close]' : {
                'click' : function(button, event, opt) {
                    var win = button.up('window');
                    win.close();
                }
            }

		})
	}
});



4.
模型 poll.js

Ext.define('App.model.poll', {
			extend : 'Ext.data.Model',
			fields : ['name', 'senority', 'department']
		});


5.
Store poll.js
Ext.define('App.store.poll', {
			extend : 'Ext.data.Store',
			autoLoad : true,
			model : 'App.model.poll',
			data : {
				'employees' : [{
							"name" : "Michael Scott",
							"senority" : 7,
							"department" : "Manangement"
						}, {
							"name" : "Dwight Schrute",
							"senority" : 2,
							"department" : "Sales"
						}, {
							"name" : "Jim Halpert",
							"senority" : 3,
							"department" : "Sales"
						}, {
							"name" : "Kevin Malone",
							"senority" : 4,
							"department" : "Accounting"
						}, {
							"name" : "Angela Martin",
							"senority" : 5,
							"department" : "Accounting"
						}]
			},
			proxy : {
				type : 'memory',
				reader : {
					type : 'json',
					root : 'employees'
				}
			}
		});



6.
视图 pollQuery.js

Ext.define('App.view.pollQuery', {
			extend : 'Ext.container.Container',
			alias : 'widget.pollQuery',
			initComponent : function() {
				var me = this;
				Ext.applyIf(me, {
							items : [{
										xtype : 'fieldset',
										margin : '10 10 0 10',
										padding : '10 10 0 10',
										collapsible : true,
										title : '信息查询',
										items : [{
													xtype : 'tabpanel',
													border : false,
													plain : true,
													activeTab : 0,
													items : [{
														xtype : 'form',
														border : false,
														padding : '10 10 10 10',
														title : '全部',
														layout : 'hbox',
                                                        closable: false
													}, {
                                                        xtype : 'form',
                                                        border : false,
                                                        padding : '10 10 10 10',
                                                        title : '高级',
                                                        layout : 'hbox',
                                                        closable: false
                                                    }],
                                                    listeners : {
                                                        'tabchange' : function(tabPanel, newCard, oldCard, pts) {
                                                            var grid = Ext.ComponentQuery.query('gridpanel')[0];
                                                            grid.setTitle(newCard.title);
                                                        }
                                                    }
												}]
									}]
						});
				me.callParent(arguments);
			},

			flushView : function() {
                this.doLayout();
			},

			loadView : function() {
                var tabpanelCmp = this.getComponent(0).getComponent(0);
				var formCmp = tabpanelCmp.getComponent(0);
                var formCmp2 = tabpanelCmp.getComponent(1);
				formCmp.add([{
							xtype : 'textfield',
							name : 'keyword',
							fieldLabel : ''
						}, {
							xtype : 'button',
							text : '搜索',
							style : 'margin-left: 20px',
                            action : 'submit'
						}, {
							xtype : 'button',
							text : '清空',
							style : 'margin-left: 10px',
                            action : 'reset'
						}]);
                        
                formCmp2.add([{
                            xtype : 'textfield',
                            name : 'keyword',
                            fieldLabel : ''
                        }, {
                            xtype : 'button',
                            text : '搜索',
                            style : 'margin-left: 20px',
                            action : 'submit2'
                        }, {
                            xtype : 'button',
                            text : '清空',
                            style : 'margin-left: 10px',
                            action : 'reset2'
                        }]);
				this.flushView();
			}
		});


视图 pollList.js

Ext.define('App.view.pollList', {
	extend : 'Ext.container.Container',
	alias : 'widget.pollList',
	requires : ['Ext.ux.RowExpander', 'Ext.grid.plugin.RowEditing'],
	initComponent : function() {
		var me = this;
		Ext.applyIf(me, {
					margin : '0 10 10 10'
				});
		me.callParent(arguments);
	},

	flushView : function() {
		this.doComponentLayout();
	},

	loadView : function() {
		var store = Ext.create('App.store.poll');

		var pagingtoolbar = Ext.create('Ext.toolbar.Paging', {
					store : store,
					displayInfo : true,
					items : ['-', {
								text : '每页显示'
							}, {
								xtype : 'combo',
								name : 'pageSize',
								displayField : 'pageSize',
								typeAhead : true,
								mode : 'local',
								forceSelection : true,
								triggerAction : 'all',
								editable : false,
								value : 15,
								width : 80,
								selectOnFocus : true,
								itemId : '#pageSize',
								store : Ext.create('Ext.data.ArrayStore', {
											fields : ['pageSize'],
											data : [[15], [20], [30], [40],
													[50]]
										})
							}, {
								text : '条'
							}, '-']
				});

		var grid = Ext.create('Ext.grid.Panel', {
			title : '全部',
			store : store,
			autoShow : true,
			selType : 'rowmodel',
			selModel : Ext.create('Ext.selection.CheckboxModel', {
						listeners : {
							selectionchange : function(sm, selections) {
								grid.down('#removeButton')
										.setDisabled(selections.length == 0);
							}
						}
					}),
			columns : [Ext.create('Ext.grid.RowNumberer'), {
						header : 'Name',
						dataIndex : 'name',
						flex : 3
					}, {
						header : 'Senority',
						dataIndex : 'senority',
						flex : 1
					}, {
						header : 'Department',
						dataIndex : 'department',
						flex : 1
					}, {
						xtype : 'actioncolumn',
						draggable : false,
						header : '操作',
						flex : 1
					}],
			plugins : [{
				ptype : 'rowexpander',
				rowBodyTpl : ['<b>Department:</b> {department}
<br>',
						'<b>Summary:</b> {name}
']
			}],
			dockedItems : [{
						xtype : 'toolbar',
						items : [{
									text : '添加',
									itemId : 'addButton',
									iconCls : 'add',
                                    action : 'add'
								}, '-', {
									itemId : 'removeButton',
									text : '删除',
									iconCls : 'remove',
									disabled : true,
                                    action : 'remove'
								}, '-']
					}]
		});

		this.add([pagingtoolbar, grid]);
		this.doComponentLayout();
	}
});


视图 pollEdit.js

Ext.define('App.view.pollEdit', {
			extend : 'Ext.window.Window',
			alias : 'widget.pollEdit',
			initComponent : function() {
				var me = this;
				Ext.applyIf(me, {
							layout : 'fit',
							title : '信息修改',
							bodyStyle : 'background:#fff; padding:10px;',
							items : [{
										xtype : 'form',
										border : false
									}],
							buttons : ['->', {
										text : '修改',
										action : 'save',
										scope : this
									}, '-', {
										text : '关闭',
										action : 'close',
										scope : this
									}]
						});
				me.callParent(arguments);
			},

			flushView : function() {
				this.doLayout();
			},

			loadView : function() {
				var formCmp = this.getComponent(0);
				formCmp.add([{
							xtype : 'textfield',
							fieldLabel : '部门名称',
							labelAlign : 'right',
							name : 'department'
						}, {
							xtype : 'textfield',
							fieldLabel : '名称',
							labelAlign : 'right',
							name : 'name'
						}, {
							xtype : 'textfield',
							fieldLabel : '调查名称',
							labelAlign : 'right',
							name : 'senority'
						}]);

				formCmp.doLayout();
				this.flushView();
			}
		});


视图 pollAdd.js

Ext.define('App.view.pollAdd', {
			extend : 'Ext.window.Window',
			alias : 'widget.pollAdd',
			initComponent : function() {
				var me = this;
				Ext.applyIf(me, {
							layout : 'fit',
							title : '信息添加',
							bodyStyle : 'background:#fff; padding:10px;',
							items : [{
										xtype : 'form',
										border : false
									}],
							buttons : ['->', {
										text : '添加',
										action : 'save',
										scope : this
									}, '-', {
										text : '关闭',
										action : 'close',
										scope : this
									}]
						});
				me.callParent(arguments);
			},

			flushView : function() {
				this.doLayout();
			},

			loadView : function() {
				var formCmp = this.getComponent(0);
				formCmp.add([{
							xtype : 'textfield',
							fieldLabel : '部门名称',
							labelAlign : 'right',
							name : 'department'
						}, {
							xtype : 'textfield',
							fieldLabel : '名称',
							labelAlign : 'right',
							name : 'name'
						}, {
							xtype : 'textfield',
							fieldLabel : '调查名称',
							labelAlign : 'right',
							name : 'senority'
						}]);

				formCmp.doLayout();
				this.flushView();
			}
		});


视图 poll.js

Ext.define('App.view.poll', {
	extend : 'Ext.container.Container',
	alias : 'widget.poll',
    autoShow : true,

	initComponent : function() {
		var me = this;
		Ext.applyIf(me, {
            items : [{
                xtype : 'pollQuery'
            }, {
                xtype : 'pollList'
            }] 
        });
		this.callParent(arguments);
	}
});


7. 效果




8. 动态加载模块
app.js
Ext.require(['Ext.app.Application']);

Ext.app.Application.implement({
	
loadModule : function(controllers) {
		var me = this;
		var controllers = Ext.Array.from(controllers), ln = controllers.length, i, controller;
		for (i = 0; i < ln; i++) {
			var name = controllers[i];
			
			/** 避免重复加载 */
			if (!this.controllers.containsKey(name)) {
				controller = Ext.create(
						this.getModuleClassName(name, 'controller'), {
							application : this,
							id : name
						});
				this.controllers.add(controller);
				controller.init(this);
				controller.onLaunch(this);

			}
		}
	}
});

var application;
Ext.application({
			name : 'App',
			appFolder : 'app',
			launch : function() {
				application = this;
				this.loadModule(['main']);
			}
		});

Ext.getApplication = function() {
	return application;
}

Ext.getController = function(name) {
    return Ext.getApplication().getController(name);
}



main.js
Ext.define('App.controller.main', {
	extend : 'Ext.app.Controller',
	refs : [{
				ref : 'tab',
				selector : 'center'
			}],
	views : ['north', 'west', 'center', 'main'],
	init : function() {
		this.control({
					'north button[action=add]' : {
						click : function() {
							var center = this.getTab();
							center.add({
										xtype : 'panel',
										title : 'Tab',
										closable : true
									});
						}
					}
				})
	}
});


main.js
Ext.define('App.view.main', {
	extend : 'Ext.container.Viewport',
	alias : 'widget.main',
	initComponent : function() {
		var me = this;
		me.callParent(arguments);
	}
});

Ext.create('App.view.main', {
    layout : 'border',
    autoShow : true,
    renderTo : Ext.getDoc(),
    title : 'ext4demo',
    items : [{
        xtype : 'north'
    }, {
        region : 'center',
        layout : 'border',
        border : false,
        split : true,
        margins : '0 5 5 5',
        minSize : 100,
        maxSize : 500,
        items : [{
                    xtype : 'west'
                }, {
                    xtype : 'center'
                }]
    }]
        
});
 


center.js

Ext.define('App.view.center', {
	extend : 'Ext.tab.Panel',
	alias : 'widget.center',

	initComponent : function() {
		var me = this;
		Ext.apply(me, {
					region : 'center',
					layout : 'fit',
					autoDestroy : true,
					resizeTabs : true,
					activeTab : 0,
                    items : [{
                        xtype : 'panel',
                        title : '欢迎'
                    }]
				})
		me.callParent(arguments);
	}

});



north.js

Ext.define('App.view.north', {
	extend : 'Ext.panel.Panel',
	alias : 'widget.north',

	initComponent : function() {
		var me = this;
		Ext.apply(me, {
			height : 0,
			region : 'north',
            items : [{
                xtype : 'button',
                text : '加载模块',
                action : 'add'
            }]
		})
		me.callParent(arguments);
	}
});



west.js

Ext.define('App.view.west', {
	extend : 'Ext.panel.Panel',
	alias : 'widget.west',

	initComponent : function() {
		var me = this;
		Ext.apply(me, {
			title : '导航',
			region : 'west',
			layout : 'accordion',
			width : 200,
			collapsible : true,
			split : true
		})
		me.callParent(arguments);
	}
});





我的 mc 框架源码在附件里.

安装要求:
jdk 1.5+
maven
tomcat
extjs 4.0.7+ 需要复制到对应目录.
index.html 可以快速了解本框架.

pom.xml 中有些包的 groupId 可能是自己定的需要注意.
由于是公司的图片资源,因此不可能上传的.





  • 大小: 68.8 KB
  • 大小: 64.2 KB
  • mc.7z (47.4 KB)
  • 下载次数: 610
  • 大小: 86.9 KB
13
8
分享到:
评论
11 楼 努力吧飞翔 2013-04-23  
10 楼 litterdeer 2012-10-23  
好东西....
9 楼 basherone 2012-09-06  
可以用,谢谢了
8 楼 amos_tl 2012-07-24  
Gamain 写道
楼主能否给一个示例源码啊,我照着做的怎么不能运行呢?


详细的错误描述?
7 楼 Gamain 2012-07-23  
楼主能否给一个示例源码啊,我照着做的怎么不能运行呢?
6 楼 amos_tl 2012-05-17  
ayanami001 写道
为什么要弄套前台的mvc呢 一直没明白

1 构建更加复杂的应用
2 便于封装组件,这个例子稍微改改就是一个增删改查的页面组件
3 代码看着更舒服
5 楼 ayanami001 2012-05-16  
为什么要弄套前台的mvc呢 一直没明白
4 楼 zouzou 2012-05-16  
能上源码更好
3 楼 JonathanWang 2012-05-16  
不错,mark以后学习。没有弄过ext,不过这个不需要后台程序么?
2 楼 zhengeili 2012-05-16  
顶一个
1 楼 pinnerc 2012-05-16  
不错,学习了。

相关推荐

    ExtJS6 MVC 精简示例

    最新版本,ExtJS6 MVC 精简示例!!!,一个可以参考的小例子!

    ExtJs 4 中的MVC应用架构

    大规模客户端应用通常不好实现不好组织也不好维护,因为功能和人力的不断增加,这些应用的规模很快就会超出掌控能力,ExtJS4带来了一个新的应用架构,不但可以组织代码,还可以减少实现的内容。

    Extjs4之MVC应用架构

    Extjs4之MVC应用架构,完整的实用例子

    extJs4.2MVC示例

    严格按照MVC架构分的曾,可以运行的extJs4.2MVC示例,在myclipse加到一个项目里的的webroot文件夹下,运行index.html即可

    EXTJS简单MVC实例

    只要将解压的文件直接放置到myeclipse的webroot下面,启动tomcat访问。简单的EXTJS mvc框架,设计 store,model,controller,view,window等等,同时展示了一些基本的点击显示、修改等等操作,需要的同学自行下载

    ExtJs 4.1 mvc 简单示例

    本例是从官方网站示例下载整理解决win7不显示json问题,ExtJs 4.1 mvc 简单示例

    ExtJS MVC示例

    配合extjs4.2.0的MVC开发模式教程使用更好

    extjs mvc简单示例

    NULL 博文链接:https://xiaolongheni.iteye.com/blog/1594739

    extjs_mvc架构_实例

    extjs_mvc架构_实例

    Extjs 4.2.0 MVC 架构 官方文档例子中文

    Extjs 4.2.0官方文档上关于MVC architecture的例子,翻译成中文

    Extjs 4 MVC Demo 示例

    原本是打算采用EXTJS4 的MVC做应用框架,已完成左侧树菜单、tabpanel(内嵌Grid,带查询及分页功能) 但是由于网络上的相关文章太少,公司对这个框架提出疑问,以后会不会遇到问题,所以改用ext3了...唉

    Extjs4应用架构设计中文WORD版

    资源名称:Extjs4 应用架构设计 中文WORD版内容简介:本文档主要讲述的是Extjs4 应用架构设计;在这篇文章,我们将会看到一个受欢迎的应用并讨论如何构建用户接口,从而创建可靠的架构。希望本文档会给有需要的朋友...

    extjs4.0 MVC 示例代码

    extjs4.0 MVC 示例代码

    Extjs 4 MVC Demo 示例 2分

    原本是打算采用EXTJS4 的MVC做应用框架,已完成左侧树菜单、tabpanel(内嵌Grid,带查询及分页功能) 但是由于网络上的相关文章太少,公司对这个框架提出疑问,以后会不会遇到问题,所以改用ext3了...唉

    EXTJS 上传组件及示例

    EXTJS 上传组件及示例EXTJS 上传组件及示例EXTJS 上传组件及示例

    EXTJS应用EXTJS应用EXTJS应用EXTJS应用

    EXTJS应用EXTJS应用EXTJS应用EXTJS应用EXTJS应用EXTJS应用

    Extjs4 MVC小实例

    Extjs4 MVC小实例根据The MVC Application Architecture做的

    EXTJS4.0 MVC 架构 GRID 应用

    基于EXT4.0 MVC 模式开发GRID DEMO 包括:GRID 分页、分组、排序、编辑等等常用功能 访问路径:http://localhost/Ext4Mvc/gridManager/gm.html

Global site tag (gtag.js) - Google Analytics