前一篇:通用权限管理系统[基于asp.net(c# 4.0) + MVC 4 + extjs 4.2 + PetaPoco](一、搭架子 - 有源码)我们搭建了基本的架子,现在我们用extjs4.2再搭一个管理后台界面出来。
打开前一篇下载好的项目源码,然后去http://www.sencha.com/products/extjs/download/ext-js-4.2.0下载extjs到/Scripts/ext-4.2/目录下,解压后的目录结构如下:
1. 在\Views\Home\目录下新建一个Login.cshtml的View文件,然后引用extjs,代码如下:
class="code_img_closed" src="/Upload/Images/2013121313/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('dc48bf8d-80b7-4d90-95ac-58c37da3f33a',event)" src="/Upload/Images/2013121313/2B1B950FA3DF188F.gif" alt="" /><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>需要验证您的身份!</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="@Url.Content("~/Scripts/include-ext.js?version=ext-4.2")"></script> <script type="text/javascript" src="@Url.Content("~/Scripts/app/login.js")"></script> </head> <body> </body> </html>Login.cshtml
2. 同样需要在HomeController建立Login方法,如下代码:
[NoAuthorize]
[ViewPage]
public ActionResult Login()
{
return View();
}
3. 最后就是用extjs来写一个登录窗口啦,见代码:
Ext.require([ 'Ext.form.*', 'Ext.tip.QuickTipManager' ]); Ext.onReady(function () { Ext.QuickTips.init(); var form = Ext.widget('form', { bodyPadding: 10, border: false, waitMsgTarget: true, fieldDefaults: { labelWidth: 90, msgTarget: 'side' }, items: [{ fieldLabel: '用户名', name: 'LoginName', xtype: 'textfield', value: 'demo', allowBlank: false, selectOnFocus: true //得到焦点时自动选择文本 }, { name: 'LoginPassword', xtype: 'textfield', fieldLabel: '密码', allowBlank: false, value: 'demo', inputType: 'password' }], buttons: [{ text: '登陆', handler: function () { form.onLogin(); } }], onLogin: function () { if (form.getForm().isValid()) { top.location.href = '/Home/Index'; } }, listeners: { render: function (panel) { panel.el.on('keypress', function (e) { if (e.getKey() == e.ENTER) { form.onLogin(); } }); } } }); var win = Ext.create('Ext.window.Window', { autoShow: true, title: '请登录', width: 280, closable: false, draggable: false, items: form, enableKeyEvents: true }); });login.js
4. 效果
1. 打开\Views\Home\Index.cshtml加入以下引用代码,其中Ext.Loader.setPath为extjs动态加载的目录所对应的命名空间:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>欢迎进入网站后台管理中心</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="@Url.Content("~/Scripts/include-ext.js?version=ext-4.2&cdn=1")"></script> <link href="@Url.Content("~/Content/css/icons.css")" type="text/css" rel="stylesheet" /> <link href="@Url.Content("~/Content/css/Niwar.css")" type="text/css" rel="stylesheet" /> <link href="@Url.Content("~/Scripts/ext-ux/portal/portal.css")" type="text/css" rel="stylesheet" /> <link href="@Url.Content("~/Scripts/ext-ux/grid/css/GridFilters.css")" type="text/css" rel="stylesheet" /> <link href="@Url.Content("~/Scripts/ext-ux/css/TabScrollerMenu.css")" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="@Url.Content("~/Scripts/ext-ux/multiupload/swfobject.js")"></script> <script type="text/javascript" src="@Url.Content("~/Scripts/ext-override.js")"></script> <script type="text/javascript"> Ext.Loader.setPath({ 'Ext.ux': '@Url.Content("~/Scripts/ext-ux")', 'Niwar.app': '@Url.Content("~/Scripts/app")' }); </script> <script type="text/javascript" src="@Url.Content("~/Scripts/app/app.js")"></script> </head> <body> <form id="history-form" class="x-hide-display"> <input type="hidden" id="x-history-field" /> <iframe id="x-history-frame"></iframe> </form> </body> </html>Index.cshtml
2. 在\Scripts\app\目录下新增app.js文件(extjs主入口文件):
Ext.Ajax.timeout = 60000; Ext.Loader.setConfig({ enabled: true }); Ext.require([ 'Ext.util.History', 'Ext.ux.statusbar.StatusBar', 'Ext.ux.portal.PortalPanel', 'Ext.ux.TabScrollerMenu', 'Ext.state.*' ]); var mainTab, //全局分页大小 globalPageSize=20, //全局时间列宽度 globalDateColumnWidth=160; Ext.onReady(function () { Ext.QuickTips.init(); Ext.History.init(); //实现浏览器的前进后退操作 var tokenDelimiter = ':'; //portal页,这里动态加载了app目录下的portal.js文件 var mainPortal = Ext.create('Niwar.app.portal', { title: '起始页' }); //多标签 mainTab = Ext.create('Ext.TabPanel', { region: 'center', margins: '2 0 0 0', deferredRender: false, activeTab: 0, plugins: [Ext.create('Ext.ux.TabCloseMenu'), { //这里加入右键关闭插件 ptype: 'tabscrollermenu', maxText: 15, pageSize: 5 }], items: [mainPortal], listeners: { tabchange: onTabChange, afterrender: onAfterRender } }); var menuTreeStore = Ext.create('Ext.data.TreeStore', { autoLoad: true, proxy: { type: 'ajax', url: '/data/menus.json', reader: { type: 'json', root: 'children' } } }); //实现树的查找,extjs4.2并不提供原生的树查找功能,我这里用到了国外用户开发的treestore的一个扩展, //见:ext-override.js var treeFilterField = Ext.create('Ext.form.field.Trigger', { width: '100%', emptyText: '功能查找...', trigger1Cls: 'x-form-clear-trigger', onTrigger1Click: function () { treeFilterField.setValue(''); menuTreeStore.clearFilter(true); }, listeners: { 'keyup': { element: 'el', fn: function (e) { var regex = new RegExp(Ext.String.escapeRegex(treeFilterField.getValue()), 'i'); menuTreeStore.clearFilter(true); menuTreeStore.filter(new Ext.util.Filter({ filterFn: function (item) { return regex.test(item.get('text')); } })); } } } }); //左边功能导航面板 var treePanel = Ext.create('Ext.tree.Panel', { id: 'menuTree', region: 'west', split: true, title: '功能导航', width: 150, stateId: 'appnav', stateful: true, margins: '2 0 0 0', collapsible: true, animCollapse: true, xtype: 'treepanel', rootVisible: false, store: menuTreeStore, tbar: [treeFilterField], bbar: [{ xtype: 'button', text: '个人中心', iconCls: 'icon_user', menu: [{ text: '修改密码', iconCls: 'icon_key', handler: function () { Niwar.openWindow('修改密码', 'profile.changpwd', 300); } }, { text: '修改资料', handler: function () { Niwar.openWindow('修改资料', 'profile.profileinfo', 300); } }, '-', { text: '安全退出', handler: function () { top.location.href = '../Home/Logout'; } }] }, { xtype: 'button', iconCls: 'icon_paint_brush', tooltip: '点击更新缓存', handler: function () { Ext.Ajax.request({ url: '../Home/ClearCache', success: function (response) { if (response.responseText != '') { var res = Ext.JSON.decode(response.responseText); Niwar.msgTip(res.msg); } } }); } }], listeners: { 'itemclick': function (e, record) { if (record.data.leaf) { Niwar.infoTip(record.data.text); } } } }); //extjs会自动渲染这个viewport var viewport = Ext.create('Ext.Viewport', { layout: 'border', items: [{ region: 'north', xtype: 'container', height: 34, id: 'app-header', layout: { type: 'hbox', align: 'middle' }, defaults: { xtype: 'component' }, items: [{ id: 'app-header-title', html: '基于Web的通用权限管理框架', width: 300 }, { id: 'app-header-r', html: '<a href="../Home/Logout" title="退出登录"><img src="/Content/images/exit.png" /></a>', flex: 1 }] }, treePanel, mainTab, { region: 'south', border: false, items: [Ext.create('Ext.ux.StatusBar', { border: false, text: 'Ready', style: 'background:#3892D3;', defaults: { style: 'color:#fff;' }, items: ['->', 'hi,欢迎回来', '-', '上次登录时间:', '上次登录IP:', '-', '版本:v1.0'] })] }] }); function onTabChange(tabPanel, tab) { var tabs = [], ownerCt = tabPanel.ownerCt, oldToken, newToken; tabs.push(tab.id); tabs.push(tabPanel.id); while (ownerCt && ownerCt.is('tabpanel')) { tabs.push(ownerCt.id); ownerCt = ownerCt.ownerCt; } newToken = tabs.reverse().join(tokenDelimiter); oldToken = Ext.History.getToken(); if (oldToken === null || oldToken.search(newToken) === -1) { Ext.History.add(newToken); } } function onAfterRender() { Ext.History.on('change', function (token) { var parts, tabPanel, length, i; if (token) { parts = token.split(tokenDelimiter); length = parts.length; for (i = 0; i < length - 1; i++) { Ext.getCmp(parts[i]).setActiveTab(Ext.getCmp(parts[i + 1])); } } }); var activeTab1 = mainTab.getActiveTab(), activeTab2 = activeTab1; onTabChange(activeTab1, activeTab2); } }); var Niwar = new Object(); //打开tab Niwar.openTab = function (tabId, tabTitle, tab, config) { var _tab = mainTab.getComponent('tab' + tabId); if (!_tab) { mainTab.setLoading('Loading...'); _tab = Ext.create('Ext.panel.Panel', { closable: true, id: 'tab' + tabId, title: tabTitle, layout: 'fit', autoScroll: true, border: false, items: typeof (tab) == 'string' ? Ext.create('Niwar.app.' + tab, config) : tab, listeners: { 'boxready': function () { mainTab.setLoading(false); } } }); mainTab.add(_tab); } mainTab.setActiveTab(_tab); } //打开window Niwar.openWindow = function (winTitle, win, winWidth, config) { Ext.create('Ext.window.Window', { autoShow: true, modal: true, title: winTitle, width: winWidth || 280, items: typeof(win) == 'string' ? Ext.create('Niwar.app.' + win, config) : win }); } //关闭tab Niwar.closeTab = function (tabId) { var tab = mainTab.getActiveTab(); tab.close(); if (tabId != undefined) { mainTab.setActiveTab(tabId); } }; //刷新ActiveTab下的gridpanel Niwar.listReload = function () { mainTab.getActiveTab().down('gridpanel').getStore().reload(); } //成功提示 Niwar.msgTip = function (msg) { function createBox(t, s) { return '<div class="msg"><h3>' + t + '</h3><p>' + s + '</p></div>'; } var msgCt; if (!msgCt) { msgCt = Ext.DomHelper.insertFirst(document.body, { id: 'msg-div' }, true); } var m = Ext.DomHelper.append(msgCt, createBox('提示:', msg), true); m.hide(); m.slideIn('t').ghost("t", { delay: 1000, remove: true }); }; //错误提示 Niwar.errTip = function (msg, e) { Ext.MessageBox.show({ title: '出错啦!', msg: msg, buttons: Ext.MessageBox.OK, animateTarget: e, icon: Ext.MessageBox.ERROR }); }; //一般提示 Niwar.infoTip = function (msg, e) { Ext.MessageBox.show({ title: '系统提示!', msg: msg, buttons: Ext.MessageBox.OK, animateTarget: e, icon: Ext.MessageBox.INFO }); }; //选择性提示 Niwar.confirmTip = function (msg,fn, buttons, e) { Ext.MessageBox.show({ title: '确认继续?', msg: msg, buttons: buttons || Ext.MessageBox.YESNO, animateTarget: e, fn: fn }); }; //拥有指定权限 Niwar.HaveAction = function (name) { return Ext.Array.contains(idata.myInfo.actions, name); } //拥有指定按钮 Niwar.HaveActionMenu = function (items, name) { if (items && items.length > 0) return Ext.Array.contains(items, name) return false; } /*字符串拼接类 用法: var buffer = new StringBuffer (); buffer.append("hello "); buffer.append("world"); var result = buffer.toString(); */ function StringBuffer() { this._strings_ = new Array(); } StringBuffer.prototype.append = function (str) { this._strings_.push(str); }; StringBuffer.prototype.toString = function () { return this._strings_.join(""); };app.js
3. 通过以上操作我们就得到了一个完整的后台管理界面(不得不赞extjs的强大功能):
网友 2014/12/12 22:55:09 发表
有源码不?
abcd 2014/11/29 17:57:50 发表
啊啊啊啊啊啊啊
网友 2014/8/13 9:17:17 发表
有源码不?
网友 2014/4/24 21:50:28 发表
挺好,咋下载呢