Extjs desktop类桌面系统的开发

最近看到extjs的类桌面系统,被其界面吸引,然后试着用extjs desktop开发了一个项目。


一》开发目录结构:

resources文件夹是我们自己定义的放资源文件,包括样式,壁纸,图片等。

modules是我项目中对应的各个窗口js模块,也是我们自己需要开发的窗口模块。

extjslib是extjs的库文件;

extjslib中core文件夹内是desktop类桌面需要的模板js类,我们也可以自己开发这种界面,或者直接调用这些类。看名字应该知道这些类的作用

css是放的extjs的默认样式与desktop的样式

ext文件是extjs的函数库跟国际化文件

images是css需要引用的图片资料


下面直接讲开发代码

首先是index.html



    
        
        Fly

        
        

        
        

        
    


    
    

然后是App.js

/*!
 * Ext JS Library 4.0
 * [email protected]
 */


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配置', 
                    iconCls: 'XXCSS', 
                    module: 'XXX'
                },{
                    name: 'xx界面', 
                    iconCls: 'XXCSS', 
                    module: 'XXX'
                },{
                    name: 'xx状态', 
                    iconCls: 'XXCSS', 
                    module: 'XXX'
                },{
                    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',
                    handler: me.onSettings,
                    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.
 * [email protected]
 * 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: '壁纸设置',
    modal: true,
    width: 640,
    height: 480,
    border: false,

    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',
            border: false,
            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", 
                        iconCls: '', 
                        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.
 * [email protected]
 * 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 = '* ';
        
        Ext.define('Fly.model.User', {
            extend: 'Ext.data.Model',
            fields: [{
                name: 'id',
                type:'int'
            },{
                name: 'userName',
                type:'string'
            },{
                name: 'userPasswd',
                type:'password'
            },{
                name: 'userPermiss'
            },{
                name: 'description',
                type:'string'
            },{
                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: "权限",
                    flex: 1,
                    dataIndex: 'userPermiss',
                    renderer:function(v){
                        if (v == 0) return "管理员";
                        if (v == 1) return "操作员";
                        if (v == 2) return "浏览员";
                    }
                },{
                    text: "描述",
                    flex: 3,
                    dataIndex: 'description'
                },{
                    text: "登陆次数",
                    flex: 1,
                    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',
                frame: true,
                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: '类型',
                    beforeLabelTextTpl: required,
                    xtype: 'combobox',
                    store: cbstore,
                    displayField: 'name',
                    valueField: 'id',
                    name: 'userPermiss',
                    forceSelection:true,
                    allowBlank:false
                },{
                    fieldLabel: '描述',
                    name: 'description',
                    xtype:'textarea'
                },{
                    id:'password',
                    fieldLabel: '密码',
                    beforeLabelTextTpl: required,
                    name: 'userPasswd',
                    blankText : '密码不能为空',
                    regex : /^[\s\S]{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: '确认密码',
                                    beforeLabelTextTpl: required,
                                    confirmPwd : {
                                        first : 'password',
                                        second : 'reUserPasswd'
                                    },
                                    inputType : 'password',
                                    vtype : 'confirmPwd',
                                    regex : /^[\s\S]{6,32}$/,
                                    regexText : '密码长度必须大于6小于32',
                                    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: '编辑',
                    maxWidth:55,
                    handler:function(){
                        var user_form = this.up('form');
                        if(user_form.getForm().isValid()){
                            user_form.getForm().submit({
                                url: 'user/updateuser.shtml',
                                submitEmptyText: false,
                                waitTitle:'请等待',
                                waitMsg: '正在编辑用户...',
                                params : {
                                    id : userid
                                },
                                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('提示', '数据验证失败!');
                        }
                    }
                },{
                    id:'user_delete',
                    text: '删除',
                    maxWidth:55,
                    handler: function() {
                        Ext.Ajax.request({
                            url:'user/delete.shtml?ids='+userid,
                            method:'post',
                            waitTitle:'请等待',
                            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();
                                }
                            },
                            failure:function(form,action){
                                Ext.Msg.alert('提示', '删除用户失败!');
                            }
                        }); 
                    }
                },{
                    text: '取消',
                    maxWidth:55,
                    handler: function() {
                        this.up('form').getForm().reset();
                    }
                }]
            });

            win = desktop.createWindow({
                id: 'users-grid',
                title:'用户管理',
                width:800,
                height:500,
                iconCls: 'icon-grid',
                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;
	}
}


你可能感兴趣的:(Extjs desktop类桌面系统的开发)