Extjs desktop类桌面系统的开发
最近看到extjs的类桌面系统,被其界面吸引,然后试着用extjs desktop开发了一个项目。 一》开发目录结构: resources文件夹是我们自己定义的放资源文件,包括样式,壁纸,图片等。 modules是我项目中对应的各个窗口js模块,也是我们自己需要开发的窗口模块。 extjslib是extjs的库文件; extjslib中core文件夹内是desktop类桌面需要的模板js类,我们也可以自己开发这种界面,或者直接调用这些类。看名字应该知道这些类的作用 css是放的extjs的默认样式与desktop的样式 ext文件是extjs的函数库跟国际化文件 images是css需要引用的图片资料 下面直接讲开发代码 首先是index.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Fly</title> <link rel="stylesheet" type="text/css" href="extjslib/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="extjslib/css/desktop.css" /> <script type="text/javascript" src="extjslib/ext/ext-all.js"></script> <script type="text/javascript" src="extjslib/ext/ext-lang-zh_CN.js"></script> <script type="text/javascript"> Ext.Loader.setConfig({enabled:true}); Ext.Loader.setPath({ //命名空间的设置 'Ext.ux.desktop': 'extjslib/core','Fly.modules': 'modules','FlyDesktop': '' }); Ext.require('FlyDesktop.App'); Ext.require('Ext.util.Cookies'); Ext.onReady(function () { Ext.create('FlyDesktop.App',{}) }) </script> </head> <body style="background-image: url(resources/wallpapers/Win7.jpg)"> </body> </html> 然后是App.js /*! * Ext JS Library 4.0 * zfeidy@qq.com */ Ext.define('FlyDesktop.App',{ extend: 'Ext.ux.desktop.App',//引用我们自己定义的模块 requires: [ 'Ext.ux.desktop.ShortcutModel','Fly.modules.SystemStatus','Fly.modules.Users','Fly.modules.BaseSetup','Fly.modules.HomeView','Fly.modules.StateCurve','Fly.modules.Settings' ],init: function() { this.callParent(); },//调用模块的方法,这里必须需要 getModules : function(){ return [ new Fly.modules.SystemStatus(),//因为最开始在index.html中Ext.Loader.setConfig({enabled:true}); //同时又命令了'Fly.modules': 'modules'的空间,所以这句话其实就是调用modules下的SystemStatus.js。 new Fly.modules.Users(),//同上 new Fly.modules.HomeView(),//同上 new Fly.modules.StateCurve(),//同上 new Fly.modules.BaseSetup() //同上 ]; },getDesktopConfig: function () { var me = this,ret = me.callParent(); // 如果这里不注释掉的话,我们可以去掉core文件夹中ShortcutModel.js, // 其实那个文件也只封装了一个model而已,同时上面的requires就不需要引用了 // Ext.define('Ext.ux.desktop.ShortcutModel',{ // extend: 'Ext.data.Model',// fields: [{ // name: 'name' // },{ // name: 'iconCls' // },{ // name: 'module' // }] // }); return Ext.apply(ret,{ contextMenuItems: [{ //鼠标右键的设置 text: '壁纸设置',handler: me.onSettings,//响应函数 scope: me },{ text: '样式设置',handler: me.onCssSettings,//响应函数 scope: me }],shortcuts: Ext.create('Ext.data.Store',{ model: 'Ext.ux.desktop.ShortcutModel',data: [{ name: 'xx管理',iconCls: 'XXCSS',module: 'users' //这个参数就是自己所开发的模块的id,这个是必须的 },{ name: 'xx配置',module: 'XXX' },{ name: 'xx界面',{ name: 'xx状态',iconCls: 'XXCSS' },{ name: 'xx曲线',iconCls: 'XXXCSS',module: 'XXX' }] }),wallpaper: 'resources/wallpapers/创意.jpg',//这里是初始化壁纸的路径 wallpaperStretch: true //初始化壁纸是否被拉伸 }); },// config for the start menu getStartConfig : function() { //开始菜单的设置(右边导航栏) var me = this,ret = me.callParent(); return Ext.apply(ret,{ title: '导航栏',iconCls: 'user',height: 300,toolConfig: { width: 100,items: [{ text:'设置',iconCls:'settings',scope: me },'-',{ text:'退出',iconCls:'logout',handler: me.onLogout,scope: me }] } }); },getTaskbarConfig: function () { //快速启动栏的设置 var ret = this.callParent(); return Ext.apply(ret,{ quickStart: [{ name: 'XX配置',iconCls: 'accordion',module: 'XXX' //参数是自己开发模块的id },{ name: 'XX界面',iconCls: 'icon-grid',module: 'XXX' }],trayItems: [{ xtype: 'trayclock',//这个是快捷栏右边的时间组件,是定义在TaskBar.js中的Ext.ux.desktop.TrayClock类。 //这个很简单,只要懂extjs就明白 flex: 1 }] }); },onLogout: function () { //退出系统的操作 Ext.Msg.confirm('退出','确认退出系统?',function(button){ if(button=="yes"){ Ext.Ajax.request({ url: 'logout.shtml',method:'POST',success: function (data) { if (typeof data == 'object') { var redata = Ext.decode(data.responseText); alert(redata.msg); Ext.util.Cookies.clear('Fly'); console.log(Ext.util.Cookies.get('Fly')); window.location = window.location.pathname+"login.html"; } } }); } }); },onSettings: function () { //设置壁纸的操作 var dlg = new Fly.modules.Settings({ //这里Fly.modules.Settings是自己写的类。另有详细解释 desktop: this.desktop }); dlg.show(); },onCssSettings: function () { Ext.create("Ext.window.Window",{ title:'样式设置',modal: true,width: 640,height: 480,border: false,layout:'fit' }).show(); } }); 接着讲下Fly.modules.Settings这个类。 这个类就是我们在modules中自己定义的Setting.js,这个 类可以当作desktop的系统类放入到core中,我因为在这里做了其他的配置操作,比如样式的控制,桌面图标的自定义排列,所以作为了一个自定义的模块。 /*! * Ext JS Library 4.0 * Copyright(c) 2006-2011 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ Ext.define('Fly.modules.Settings',{ extend: 'Ext.window.Window',uses: [ 'Ext.tree.Panel','Ext.tree.View','Ext.form.field.Checkbox','Ext.layout.container.Anchor','Ext.layout.container.Border','Ext.ux.desktop.Wallpaper' ],layout: 'anchor',title: '壁纸设置',initComponent: function () { var me = this; Ext.define('WallpaperModel',{ extend: 'Ext.data.Model',fields: [{ name: 'text' },{ name: 'img' }] }); me.selected = me.desktop.getWallpaper(); me.stretch = me.desktop.wallpaper.stretch; me.preview = Ext.create('widget.wallpaper'); //调用extjs中core中的壁纸模板类 me.preview.setWallpaper(me.selected); me.tree = me.createTree(); me.buttons = [ { text: '确定',handler: me.onOK,scope: me },{ text: '取消',handler: me.close,scope: me } ]; me.items = [ { anchor: '0 -30',layout: 'border',items: [ me.tree,{ xtype: 'panel',title: '预览',region: 'center',layout: 'fit',items: [ me.preview ] } ] },{ xtype: 'checkbox',boxLabel: '拉伸适合屏幕',checked: me.stretch,listeners: { change: function (comp) { me.stretch = comp.checked; } } } ]; me.callParent(); },createTree : function() { var me = this; function child (img) { return { img: img,text: me.getTextOfWallpaper(img),iconCls: '',leaf: true }; } var tree = new Ext.tree.Panel({ title: '壁纸',rootVisible: false,lines: false,autoScroll: true,width: 150,region: 'west',split: true,minWidth: 100,listeners: { afterrender: { fn: this.setInitialSelection,delay: 100 },select: this.onSelect,scope: this },store: new Ext.data.TreeStore({ model: 'WallpaperModel',//初始化壁纸 root: { text:'壁纸',expanded: true,children:[ child('Win7.jpg'),child('净土.jpg'),child('创意.jpg'),child('卡通.jpg'),child('山水.jpg'),child('幻境.jpg'),child('幻想.jpg'),child('梦想.jpg'),child('水滴.jpg'),child('祥和.jpg'),child('雪地.jpg'),child('战马.jpg'),{ text: "None",leaf: true }] } }) }); return tree; },getTextOfWallpaper: function (path) { var text = path,slash = path.lastIndexOf('/'); if (slash >= 0) { text = text.substring(slash+1); } var dot = text.lastIndexOf('.'); text = Ext.String.capitalize(text.substring(0,dot)); text = text.replace(/[-]/g,' '); return text; },onOK: function () { var me = this; if (me.selected) { me.desktop.setWallpaper(me.selected,me.stretch); } me.destroy(); },onSelect: function (tree,record) { var me = this; if (record.data.img) { //指定壁纸的路径 me.selected = 'resources/wallpapers/' + record.data.img; } else { me.selected = Ext.BLANK_IMAGE_URL; } me.preview.setWallpaper(me.selected); },setInitialSelection: function () { var s = this.desktop.getWallpaper(); if (s) { var path = '/Wallpaper/' + this.getTextOfWallpaper(s); this.tree.selectPath(path,'text'); } } }); 有了上面这几个部分 我们其实就可以构建一个桌面系统了 然后我插入一个自定义的模块功能Users.js /*! * Ext JS Library 4.0 * Copyright(c) 2006-2011 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ Ext.define('Fly.modules.Users',{ extend: 'Ext.ux.desktop.Module',requires: [ 'Ext.data.JsonStore','Ext.util.Format','Ext.grid.Panel','Ext.grid.RowNumberer' ],id:'users',init : function(){ this.launcher = { text: '用户管理',iconCls:'icon-grid' }; },createWindow : function(){ var desktop = this.app.getDesktop(); var win = desktop.getWindow('users-grid'); var required = '<span style="color:red;font-weight:bold" data-qtip="Required">* </span>'; Ext.define('Fly.model.User',fields: [{ name: 'id',type:'int' },{ name: 'userName',type:'string' },{ name: 'userPasswd',type:'password' },{ name: 'userPermiss' },{ name: 'description',{ name: 'logintimes',type:'int' }] }); var userStore = Ext.create('Ext.data.Store',{ autoLoad: true,autoDestroy: true,storeId: 'userStore',model:'Fly.model.User',proxy: { actionMethods:{ create: "POST",read: "POST",update: "POST",destroy: "POST" },type: 'ajax',api: { create : 'user/adduser.shtml',read : 'user/userslist.shtml',update : 'user/updateuser.shtml',destroy : 'user/delete.shtml' },reader: { type: 'json',root: 'rows',idProperty: 'id' } } }); //下拉框数据。 var cbstore = Ext.create('Ext.data.ArrayStore',{ autoDestroy : true,fields: ['id','name'],data : [[0,"管理员"],[1,"操作员"],[2,"浏览员"]] }); Ext.apply(Ext.form.VTypes,{ confirmPwd : function(val,field) { if (field.confirmPwd) { var firstPwdId = field.confirmPwd.first; var secondPwdId = field.confirmPwd.second; this.firstField = Ext.getCmp(firstPwdId); this.secondField = Ext.getCmp(secondPwdId); var firstPwd = this.firstField.getValue(); var secondPwd = this.secondField.getValue(); if (firstPwd == secondPwd) { return true; } else { return false; } } },confirmPwdText : '两次输入的密码不一致!' }); if(!win){ var userid; var usergrid = Ext.create('Ext.grid.Panel',{ flex:2,frame: true,title:'用户列表',store: userStore,layout: 'column',columns: [ new Ext.grid.RowNumberer(),{ text: "ID",flex: 1,dataIndex: 'id' },{ text: "用户名",flex: 2,dataIndex: 'userName' },{ text: "权限",dataIndex: 'userPermiss',renderer:function(v){ if (v == 0) return "管理员"; if (v == 1) return "操作员"; if (v == 2) return "浏览员"; } },{ text: "描述",flex: 3,dataIndex: 'description' },{ text: "登陆次数",dataIndex: 'logintimes' }],listeners: { selectionchange: function(model,records) { if (records[0]) { userid = records[0].data.id; Ext.getCmp('userForm').loadRecord(records[0]); Ext.getCmp('user_save').setDisabled(false); Ext.getCmp('userForm').remove('reUserPasswd'); Ext.getCmp('user_update').setDisabled(false); Ext.getCmp('user_delete').setDisabled(false); Ext.getCmp('user_save').setText('增加'); } } } }); var userform = Ext.widget({ flex:1,title:'用户编辑',xtype: 'form',id: 'userForm',bodyPadding: 10,layout:'anchor',fieldDefaults: { labelStyle:'font-weight: bold;text-align:right',labelWidth: 70 },defaultType: 'textfield',items: [{ id:'user-name',fieldLabel: '用户名',beforeLabelTextTpl: required,name: 'userName',allowBlank:false,enableKeyEvents: true,listeners:{ //事件监听,当用户离开输入框——失去焦点时执行 'blur':function(){ Ext.Ajax.request({ url:'checkname.shtml?loginName='+Ext.getCmp('user-name').getValue(),method:'post',success: function(response,opts){ var respText=Ext.decode(response.responseText); if(respText.success == true){ //根据ajax请求返回的数据信息手动的进行设置该字段无效 Ext.getCmp('user-name').markInvalid('该用户名已被使用'); } } }); } } },{ fieldLabel: '类型',xtype: 'combobox',store: cbstore,displayField: 'name',valueField: 'id',name: 'userPermiss',forceSelection:true,allowBlank:false },{ fieldLabel: '描述',name: 'description',xtype:'textarea' },{ id:'password',fieldLabel: '密码',name: 'userPasswd',blankText : '密码不能为空',regex : /^[sS]{6,32}$/,regexText : '密码长度必须大于6小于32',inputType : 'password',allowBlank:false }],buttons: [{ id:'user_save',text: '增加',maxWidth:55,handler:function(){ var user_form = this.up('form'); if(this.getText() == '增加'){ if(!Ext.get('reUserPasswd')){ user_form.add({ id:'reUserPasswd',name:'reUserPasswd',fieldLabel: '确认密码',confirmPwd : { first : 'password',second : 'reUserPasswd' },vtype : 'confirmPwd',allowBlank:false }) } user_form.getForm().reset(); Ext.getCmp('user_update').setDisabled(true); Ext.getCmp('user_delete').setDisabled(true); this.setText('保存'); }else{ if(user_form.getForm().isValid()){ user_form.getForm().submit({ url: 'user/adduser.shtml',submitEmptyText: false,waitTitle:'请等待',waitMsg: '正在添加用户...',success:function(form,action){ var response = Ext.decode(action.response.responseText); Ext.Msg.alert('提示',response.msg); userStore.load(); },failure:function(form,action){ Ext.Msg.alert('提示','添加用户失败!'); } }); }else{ Ext.Msg.alert('提示','数据验证失败!'); } this.setText('增加'); Ext.getCmp('userForm').remove('reUserPasswd'); Ext.getCmp('user_update').setDisabled(false); Ext.getCmp('user_delete').setDisabled(false); } } },{ id:'user_update',text: '编辑',handler:function(){ var user_form = this.up('form'); if(user_form.getForm().isValid()){ user_form.getForm().submit({ url: 'user/updateuser.shtml',waitMsg: '正在编辑用户...',params : { id : userid },action){ var response = Ext.decode(action.response.responseText); Ext.Msg.alert('提示',response.msg); userStore.load(); },action){ Ext.Msg.alert('提示','编辑用户失败!'); } }); }else{ Ext.Msg.alert('提示','数据验证失败!'); } } },{ id:'user_delete',text: '删除',handler: function() { Ext.Ajax.request({ url:'user/delete.shtml?ids='+userid,waitMsg: '正在删除用户...',params : { id : userid },success:function(response,opts){ var respText=Ext.decode(response.responseText); if(respText.success == true){ Ext.Msg.alert('提示',respText.msg); userStore.load(); } },action){ Ext.Msg.alert('提示','删除用户失败!'); } }); } },{ text: '取消',handler: function() { this.up('form').getForm().reset(); } }] }); win = desktop.createWindow({ id: 'users-grid',title:'用户管理',width:800,height:500,layout: { type: 'hbox',align: 'stretch',defaultMargins:{ top: 1,right: 1,bottom: 1,left: 1 },padding:0 },items: [ usergrid,userform ] }); } return win; } }); 这里所定义的 id:'users',就是前面module参数需要引用的。 最后一点是,如果想在一个窗口中调用另一个窗口,可以使用下面的方法: 比如我们点击一个窗口中的按钮,想打开另一个窗口 xtype:'button',handler:function(){ var module = me.app.getModule('#另一个窗口的ID'),win = module && module.createWindow(); if (win) { if (win.isVisible()) { win.restore(); win.toFront(); } else { win.show(); } return win; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- OK6410(256M RAM ,2G SLC NAND)Uboot-2013-04移植
- reactjs – (Universal React redux react-router)如何避免
- 使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
- 解决win 10下git bash中文乱码
- ruby-on-rails – 如何对options_for_select哈希进行排序?
- ajax实现网页的局部刷新
- ajax查询数据库时数据无法更新的问题
- jsonConfig详细使用
- cocos2dx 用字符串创建按钮之 ControlButton
- nagios监控实例 -- PostgreSQL监控