当前位置: 代码迷 >> JavaScript >> [ExtJS] MVC应用架构示范
  详细解决方案

[ExtJS] MVC应用架构示范

热度:211   发布时间:2012-08-28 12:37:01.0
[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('grid')[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',
								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];
			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);
	}
});




1 楼 pinnerc 2012-05-16  
不错,学习了。
2 楼 zhengeili 2012-05-16  
顶一个
3 楼 JonathanWang 2012-05-16  
不错,mark以后学习。没有弄过ext,不过这个不需要后台程序么?
4 楼 zouzou 2012-05-16  
能上源码更好
5 楼 ayanami001 2012-05-16  
为什么要弄套前台的mvc呢 一直没明白
6 楼 amos_tl 2012-05-17  
ayanami001 写道
为什么要弄套前台的mvc呢 一直没明白

1 构建更加复杂的应用
2 便于封装组件,这个例子稍微改改就是一个增删改查的页面组件
3 代码看着更舒服
  相关解决方案