ExtJS4.2学习(21)动态菜单与表格数据展示操作总结篇2

运行效果:

此文介绍了根据操作左侧菜单在右面板展示相应内容。

 

一、主页

先看一下跳转主页的方式:由在webapp根目录下的index.jsp跳转至demo的index.jsp

下面是demo的index.jsp的代码

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setHeader("Expires","0");request.setCharacterEncoding("UTF-8");    //String webRoot = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首页</title>
<link href="../ExtJS4.2/resources/css/ext-all-neptune-rtl.css" rel="stylesheet">
<link href="../ExtJS4.2/css/icon.css" rel="stylesheet">
<script src="../ExtJS4.2/ext-all.js"></script>
<script src="../ExtJS4.2/locale/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="js/localXHR.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</head>
<body><div id="north-div" style="height: 73px; background-color: #101010;"><img alt="思考者日记网|束洋洋个人博客" src="image/shuyangyang_01.jpg"></div><div id="south-div" align="center">Copyright by 束洋洋&copy; www.shuyangyang.com.cn</div><div id="div2"></div>
</body>
</html>

看样看到此页面在引用文件的地方会加载2个自定义的js,在body处定义了页面所包含的两个dom元素。

先贴出笔者看不懂的localXHR.js

if (document.location.protocol == 'file:') {Ext.override(Ext.data.Connection, {parseStatus: function() {return {success: true,isException: false};}});}

然后是index.js

Ext.Loader.setConfig({enabled : true
});Ext.Loader.setPath({'Ext.ux' : '../ExtJS4.2/ux'//设置命名空间的路径
});Ext.require(['Ext.ux.TabCloseMenu']);//动态加载

Ext.onReady(function() {var rightPanel = Ext.create('Ext.tab.Panel', {activeTab : 0,border : false,autoScroll : true,//iconCls:'Applicationviewlist',region : 'center',items : [{title : '首页',iconCls: 'House',html: '<iframe frameborder="no" border=0 height="100%" width="100%" src="blank.jsp" scrolling="auto"></iframe>',}],plugins: [Ext.create('Ext.ux.TabCloseMenu',{//选项卡关闭插件closeTabText: '关闭当前',//The text for closing the current tab.closeOthersTabsText: '关闭其他',//The text for closing all tabs except the current one.closeAllTabsText: '关闭所有'//The text for closing all tabs.
                          })]});var tree = Ext.create("Ext.panel.Panel", {height : '70%',//设置高度region : 'north',layout : {// layout-specific configs go heretype : 'accordion',titleCollapse : true,//允许通过点击标题栏的任意位置来展开/收缩子项Panelanimate : true,// 动画切换效果activeOnTop : false// 折叠展开是否改变菜单顺序
        },layoutConfig : {animate : true},split : true});// 左边下部Panelvar detailsPanel = {id : 'details-panel',iconCls : "User",collapsible : true, // 是否折叠title : '信息',region : 'center',bodyStyle : 'padding-bottom:15px;background:#eee;',autoScroll : true,html : '<p class="details-info">用户名:束洋洋<br />部&nbsp;&nbsp;&nbsp;门:管理部<br />登录IP:156.15.26.101</p>'};// 左边下部Panel结束var model = Ext.define("TreeModel", { // 定义树节点数据模型extend : "Ext.data.Model",fields : [{name : "id",type : "string"},{name : "text",type : "string"},{name : "iconCls",type : "string"},{name : "leaf",type : "boolean"},{name : 'url',type:"string"},{name : 'description',type:"string"}]});//组建树,返回Ext.tree.Panelvar buildTree = function(json) {return Ext.create('Ext.tree.Panel', {rootVisible : false,//false,隐藏根节点。border : false,//隐藏此树面板的边框lines:false,//false,树用的线置为disable。autoScroll:true,//自动显示滚动条useArrows:true,store : Ext.create('Ext.data.TreeStore', {//(必须的) Store树的数据源. 一个TreePanel必须绑定一个Ext.data.TreeStore。model : model,//定义当前store对象的Model数据模型root : {//当前store的根节点。expanded : true,//展开根节点。(因为根节点被设置为隐藏,所以在此可以不用设置此属性)children : json.children//子节点数组。
                                }}),listeners : {//配置监听'itemclick' : function(view, record, item, index, e) {//选项的单击事件。单击选项时触发。--Ext.view.View-event-itemclickvar leaf = record.get('leaf');//获取当前选项的leaf——是否为叶子节点//var typeId = record.get("TYPE_ID");var text = record.get('text');//获取当前选项的文本var icon = record.get('iconCls');//获取当前选项的图标var url = record.get('url');//获取当前选项的地址if (leaf) { //判断点击的是否是叶子节点,如果是,创建一个Panelvar panel = Ext.create('Ext.panel.Panel',{title : text,//标题closable : true,//该属性配置为true,这个窗体的'close'工具按钮便会展现出来并且允许用户通过点击这个按钮来关闭这个窗体,false则相反。iconCls : icon,//左侧图标html : '<iframe width="100%" height="100%" frameborder="0" src='+url+'></iframe>'//一个 HTML片段——这个Panel的内容
                                        });rightPanel.add(panel);//右面板(Ext.tab.Panel)添加此组件rightPanel.setActiveTab(panel);//使此组件处于活动状态
                                    }/*var id = record.get('id');var text = record.get('text');var leaf = record.get('leaf');if (leaf) {alert('id-' + id + ',text-' + text+ ',leaf-' + leaf);}*/},scope : this//The scope (this reference) in which the handler is executed. Defaults to the browser window.
                            }});};// 整体架构容器Ext.create("Ext.container.Viewport", {layout : 'border',items : [ {region : 'north',//北方contentEl : 'north-div',//指定一个已存在的HTML元素, 或者一个已存在HTML元素的 id , 它们将被用作当前组件的内容.height : 73,bodyStyle : 'background-color:#BBCCEE;'}, {region : 'south',//南方contentEl : 'south-div',height : 20,bodyStyle : 'background-color:#BBCCEE;'}, {layout : 'border',title : '菜单',id : 'layout-browser',region : 'west',//西方border : false,split : true,margins : '2 0 5 5',width : 200,//minSize : 10,//无效设置//maxSize : 50,//无效设置autoScroll : false,collapsible : true, // 是否折叠//iconCls : "Application",items : [ tree, detailsPanel ]//包含树面板、个人简介面板。注:子组件的相对位置在子组件里设置,如在tree中设置了height属性,就指定了tree的相对高度。
        },rightPanel],listeners : {//监听。这里用来添加树面板里的菜单afterrender : function() {//在组件渲染完成之后触发.Ext.AbstractComponentExt.getBody().mask('正在加载系统菜单....');//显示遮罩层Ext.Ajax.request({//向服务端发送ajax请求url:'../../menu/showMenu',//请求地址success : function(response) {//成功响应的回调函数。response:包含了响应数据的XMLHttpRequest对象.Ext.getBody().unmask();//隐藏先前应用的遮罩层.var json = Ext.JSON.decode(response.responseText);//获取返回的文本并解析为json格式。Ext.JSON.decode(..):解码(解析)JSON字符串对象。if(json.code == 'OK'){Ext.each(json.data, function(el) {//迭代一个数组或是可迭代的值,在每个元素上调用给定的回调函数 var panel = Ext.create('Ext.panel.Panel', {//创建一个Panelid : el.id,//定义idtitle : el.text,//定义标题iconCls:el.iconCls,//定义图标leaf    :el.leaf,//定义leaf。Ext.data.NodeInterface-cfg-leaf:设置为true表明本节点没有子节点。 不会为本节点渲染展开图标或箭头。layout : 'fit'//定义布局。fit:当容器只包含一个子元素时, 子元素自动填满容器
                                 });panel.add(buildTree(el));//当前Panel添加由此节点的子节点所创建的树面板tree.add(panel);//tree(1个Panel)添加当前Panel
                             });}else{}},failure : function(request) {Ext.MessageBox.show({title : '操作提示',msg : "连接服务器失败",buttons : Ext.MessageBox.OK,icon : Ext.MessageBox.ERROR});},method : 'post'//请求的方式
                 });}}});
});

 

分析:

1.插件。当前页面使用了选项卡关闭插件(Ext.ux.TabCloseMenu),效果如下:

因此需要加载Ext.ux.TabCloseMenu类,如下:

Ext.Loader.setConfig({enabled : true
});Ext.Loader.setPath({'Ext.ux' : '../ExtJS4.2/ux'//设置命名空间的路径
});Ext.require(['Ext.ux.TabCloseMenu']);//动态加载

这里有个小疑惑:采用Ext.require的方式加载类,还是“动态加载”吗?因为从表面上看在加载index.js时就会加载Ext.ux.TabCloseMenu类。不管怎样,这里把它加载就好。

2.页面布局

2.1 整体布局:整体采用Ext.container.Viewport的布局方式,其内部子组件采用border的布局方式,如下片段代码:

// 整体架构容器Ext.create("Ext.container.Viewport", {layout : 'border',items : [ {region : 'north',//北方contentEl : 'north-div',//指定一个已存在的HTML元素, 或者一个已存在HTML元素的 id , 它们将被用作当前组件的内容.height : 73,bodyStyle : 'background-color:#BBCCEE;'}, {region : 'south',//南方contentEl : 'south-div',height : 20,bodyStyle : 'background-color:#BBCCEE;'}, {layout : 'border',title : '菜单',id : 'layout-browser',region : 'west',//西方border : false,split : true,margins : '2 0 5 5',width : 200,//minSize : 10,//无效设置//maxSize : 50,//无效设置autoScroll : false,collapsible : true, // 是否折叠//iconCls : "Application",items : [ tree, detailsPanel ]//包含树面板、个人简介面板。注:子组件的相对位置在子组件里设置,如在tree中设置了height属性,就指定了tree的相对高度。
        },rightPanel],

当Ext.container.Viewport采用border的布局方式,那么子组件的方位(东、南、西、北/中心)由子组件的region属性指定。上面的rightPanel组件在上面虽看不出,但在其内部定义了region : 'center'——在中心显示。

2.2 树面板(TreePanel)布局

此文中的树面板布局相对其他组件的布局相对复杂,为了方便说明,下面将树面板中accordion的布局方式去掉:

var tree = Ext.create("Ext.panel.Panel", {height : '70%',//设置高度region : 'north',/*layout : {// layout-specific configs go heretype : 'accordion',titleCollapse : true,//允许通过点击标题栏的任意位置来展开/收缩子项Panelanimate : true,// 动画切换效果activeOnTop : false// 折叠展开是否改变菜单顺序},*/layoutConfig : {animate : true},split : true});

去掉以后的显示效果:

上图说明了树面板的结构。在创建树面板的过程中,首先根据菜单的一级菜单创建一个Panel,然后再添加由此一级菜单的子菜单所创建的TreePanel,最后由tree(一个Panel)再把这个Panel添加进去。相应的代码如下:

                             Ext.each(json.data, function(el) {var panel = Ext.create('Ext.panel.Panel', {//创建一个Panelid : el.id,title : el.text,iconCls:el.iconCls,leaf    :el.leaf,layout : 'fit'
                                 });panel.add(buildTree(el));//当前Panel添加TreePaneltree.add(panel);//tree添加当前Panel});

3.事件

在index.js涉及了2个事件:

一是在创建Ext.container.Viewport容器时所设置的‘afterrender’事件,这个事件用于向服务端发送请求以往tree面板中添加菜单;下面看一下代码 Ext.container.Viewport

        listeners : {//监听。这里用来添加树面板里的菜单afterrender : function() {//在组件渲染完成之后触发。--Ext.container.ViewportExt.getBody().mask('正在加载系统菜单....');Ext.Ajax.request({url:'../../menu/showMenu',success : function(response) {//成功响应的回调函数。response:包含了响应数据的XMLHttpRequest对象.Ext.getBody().unmask();//隐藏先前应用的遮罩层.var json = Ext.JSON.decode(response.responseText);//获取返回的文本并解析为json格式。Ext.JSON.decode(..):解码(解析)JSON字符串对象。if(json.code == 'OK'){Ext.each(json.data, function(el) {//迭代一个数组或是可迭代的值,在每个元素上调用给定的回调函数var panel = Ext.create('Ext.panel.Panel', {id : el.id,title : el.text,iconCls:el.iconCls,leaf    :el.leaf,layout : 'fit'
                                 });panel.add(buildTree(el));//当前Panel添加TreePaneltree.add(panel);//tree添加当前Panel
                             });}else{}},failure : function(request) {Ext.MessageBox.show({title : '操作提示',msg : "连接服务器失败",buttons : Ext.MessageBox.OK,icon : Ext.MessageBox.ERROR});},method : 'post'//请求的方式
                 });}}

注:事件名可以加单引号'',也可以不加.

 

二是在创建树面板中中Ext.data.TreeStore的‘itemclick’事件——此事件是用来在点击左侧菜单时,向右边的面板(选项卡)添加一个选项卡面板,下面再看一下这里的代码

                            listeners : {//配置监听'itemclick' : function(view, record, item, index, e) {//选项的单击事件。单击选项时触发。--Ext.tree.Panelvar leaf = record.get('leaf');//var typeId = record.get("TYPE_ID");var text = record.get('text');var icon = record.get('iconCls');var url = record.get('url');//获取当前选项的地址if (leaf) { //判断点击的是否是叶子节点,如果是,创建一个Panelvar panel = Ext.create('Ext.panel.Panel',{title : text,//标题closable : true,//该属性配置为true,这个窗体的'close'工具按钮便会展现出来并且允许用户通过点击这个按钮来关闭这个窗体,false则相反。iconCls : icon,//左侧图标html : '<iframe width="100%" height="100%" frameborder="0" src='+url+'></iframe>'//一个 HTML片段——这个Panel的内容
                                        });rightPanel.add(panel);//右面板(Ext.tab.Panel)添加此组件rightPanel.setActiveTab(panel);//使此组件处于活动状态
                                    }},scope : this//The scope (this reference) in which the handler is executed. Defaults to the browser window.}

这个‘itemclick’事件来自于Ext.tree.Panel,从此事件可知,当点击左边的菜单时,首先会判定该菜单是否为叶子节点,如果是,则会创建一个Panel,这个Panel含有标题,图标,html等属性,然后右选项卡面板会将此面板添加进去并将其设置为可活动的。需注意的是,由于所添加的Panel里的html属性是一个iframe,所以在渲染时会把iframe里的src所在资源页面包含进来。

 

功能

一、用户管理

当点击菜单选项中的“用户管理”,那么在rightPanel(选项卡面板)会添加一个子选项卡,此子选项卡有一个html配置,它是一个iframe,其中的src为:/demo/UserMan/index.jsp——即此菜单的url值。这样“用户管理”这个子选项卡就会包含这个页面。下面看一下这个页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setHeader("Expires","0");request.setCharacterEncoding("UTF-8");    //String webRoot = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户管理</title>
<link href="../../ExtJS4.2/resources/css/ext-all-neptune-rtl.css" rel="stylesheet">
<link href="../../ExtJS4.2/css/icon.css" rel="stylesheet">
<script src="../../ExtJS4.2/ext-all.js"></script>
<script src="../../ExtJS4.2/locale/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="../js/localXHR.js"></script>
<script type="text/javascript" src="../js/userMan.js"></script>
</head>
<body>
</body>
</html>

可以看出这个页面除了引用文件说明什么也没有,这就对了,因为所有的内容在userMan.js中。下面看一下userMan.js

//引入扩展组件
Ext.Loader.setConfig({enabled: true});Ext.Loader.setPath('Ext.ux', '../../ExtJS4.2/ux/');Ext.require(['Ext.data.*','Ext.grid.*','Ext.util.*','Ext.tip.QuickTipManager','Ext.ux.data.PagingMemoryProxy','Ext.ux.ProgressBarPager'
]);Ext.onReady(function() {//创建列var columns = [{xtype: 'rownumberer'},//创建Ext.grid.RowNumberer的实例。Ext.grid.RowNumberer:它是一个为每行提供编号的列。{header:'编号',dataIndex:'id',hidden: true},{header:'用户名',dataIndex:'name'},{header:'年龄',dataIndex:'age'},//年龄{header:'性别',dataIndex:'sex',renderer:function(value){  if(value=='男'){  return "<span style='color:green;font-weight:bold';>男</span>";  } else {  return "<span style='color:red;font-weight:bold';>女</span>";  }}},{header:'地址',dataIndex:'address'},{header:'身份证号码',dataIndex:'cardId',width:150},{header:'角色',dataIndex:'roleId'},{header:'部门',dataIndex:'deptId'}];//创建仓库var store = Ext.create("Ext.data.Store",{pageSize:20, //每页显示几条数据//采用代理方式向服务端发送请求,获取数据
        proxy:{  type:'ajax',  url:'/user/showUser',  reader:{  type:'json',  totalProperty:'total',//总记录数root:'data', //数据idProperty:'id'  //主键
            }  },  fields:[  //字段。reader是根据这里的字段信息来解析返回的数据的。{name:'id'}, //mapping:0 这样的可以指定列显示的位置,0代表第1列,可以随意设置列显示的位置  {name:'name'},  {name:'age'},  {name:'sex'},{name:'address'},{name:'cardId'},{name:'roleId'},{name:'deptId'}]  });var sm = Ext.create('Ext.selection.CheckboxModel');var grid = Ext.create("Ext.grid.Panel",{region: 'center',border: false,store: store,selModel: sm,//选择模式是“复选框”
        columns: columns,region: 'center', //框架中显示位置,单独运行可去掉此段loadMask:true, //显示遮罩和提示功能,即加载Loading……  forceFit:true, //自动填满表格  columnLines:false, //列的边框rowLines:true, //设置为false则取消行的框线样式
        dockedItems: [{xtype:'toolbar',dock:'top',displayInfo: true,items:[{ xtype: 'textfield',name: 'name',fieldLabel: '用户名',labelAlign:'left',labelWidth:65},{ xtype: 'textfield',name: 'dept',fieldLabel: '部门',labelAlign:'left',labelWidth:35},{ xtype: 'textfield',name: 'role',fieldLabel: '角色',labelAlign:'left',labelWidth:35},{ xtype: 'button', text: '查询',iconCls:'Usermagnify'},{ xtype: 'button', text: '显示全部',iconCls:'Applicationformmagnify'}]},{xtype:'toolbar',dock:'top',displayInfo: true,items:['-',{ xtype: 'button', text: '增加用户',iconCls:'Useradd',listeners: {click:function(){Ext.Msg.alert("增加用户","增加用户啦");}}},'-',{ xtype: 'button', id:'editUser', text: '编辑用户',disabled:true,iconCls:'Useredit',//disabled:true 该button处于禁用状态
                       listeners: {click:function(){Ext.Msg.alert("编辑用户","编辑用户啦");}}},'-',{ xtype: 'button', id:'delUser', text: '删除用户',disabled:true,iconCls:'Userdelete',listeners: {click:function(){Ext.Msg.alert("删除用户","删除用户啦");}}},'-',{ xtype: 'button', id:'allotUser', text: '分配角色',disabled:true,iconCls:'Usergo',listeners: {click:function(){Ext.Msg.alert("分配","分配用户啦");}}},{ xtype: 'button', text: '导入',iconCls:'Databasecopy',listeners: {click:function(){Ext.Msg.alert("导入","导入用户啦");}}},'-',{ xtype: 'button', text: '导出',iconCls:'Pagewhiteoffice',menu:{//菜单属性items:[{//子组件的默认xtype是paneltext:'导出EXCEL',iconCls:'Pageexcel',listeners: {click:function(){Ext.Msg.alert("导出Excel","导出Excel");}}},{text:'导出CSV',iconCls:'Pagegreen',listeners: {click:function(){//Ext.getCmp('editUser').setDisabled(true);Ext.Msg.alert("导出CSV","导出CSV");}}}]}},'-',{ xtype: 'button', text: '打印',iconCls:'Printer',listeners: {click:function(){Ext.Msg.alert("打印","打印");}}}],},{xtype: 'pagingtoolbar',//分页工具栏store: store,   // GridPanel使用相同的数据源dock: 'bottom',displayInfo: true,plugins: Ext.create('Ext.ux.ProgressBarPager'),//分页进度条emptyMsg: "没有记录" //没有数据时显示信息
        }]});//加载数据store.load({params:{start:0,limit:20}}); // 表格配置结束//监听表格(为表格的选择模型添加selectionchange事件)grid.getSelectionModel().on({//getSelectionModel:返回grid的选择模型。on:是addListener的简写方法selectionchange: function(sm, selections) {//一个选项发生改变之后触发。参数:selections:选择的记录if (selections.length) {//如果有被选中的记录,则‘修改用户’、‘删除用户’、‘分配角色’三个按钮设置为可用状态Ext.getCmp('editUser').setDisabled(false);//getCmp:返回指定id的组件Ext.getCmp('delUser').setDisabled(false);Ext.getCmp('allotUser').setDisabled(false);} else {//反之,这三个按钮设置为禁用状态。Ext.getCmp('editUser').setDisabled(true);Ext.getCmp('delUser').setDisabled(true);Ext.getCmp('allotUser').setDisabled(true);}}});//表格右键菜单  var contextmenu = new Ext.menu.Menu({  id:'theContextMenu',  items:[{  text:'增加用户',iconCls:'Useradd',handler:function(){  Ext.Msg.alert("系统提示","增加用户");  }  },'-',{  text:'编辑用户',iconCls:'Useredit',handler:function(){  Ext.Msg.alert("系统提示","编辑用户");  }  },'-',{  text:'删除用户',iconCls:'Userdelete',handler:function(){  Ext.Msg.alert("系统提示","删除用户");  }  },'-',{  text:'分配角色',iconCls:'Usergo',handler:function(){  Ext.Msg.alert("系统提示","分配角色");  }  },'-',{  text:'导入',iconCls:'Databasecopy',handler:function(){  Ext.Msg.alert("系统提示","导入");  }  },'-',{  text:'导出',iconCls:'Pagewhiteoffice',menu:{items:[{text:'导出EXCEL',iconCls:'Pageexcel',listeners: {click:function(){Ext.Msg.alert("导出Excel","导出Excel");}}},{text:'导出CSV',iconCls:'Pagegreen',listeners: {click:function(){//Ext.getCmp('editUser').setDisabled(true);Ext.Msg.alert("导出CSV","导出CSV");}}}]}},'-',{  text:'打印',iconCls:'Printer',handler:function(){  Ext.Msg.alert("系统提示","打印");  }  }]  });  //为表格添加右键菜单事件grid.on("itemcontextmenu",function(view,record,item,index,e){ //on:addListener的简写方法. itemcontextmenu:选项的右键菜单事件 右键单击选项时触发。e.preventDefault();  //阻止浏览器默认行为处理事件。--Ext.EventObjectcontextmenu.showAt(e.getXY());  //contextmenu在特定的XY位置显示。 getXY:获取事件的页面坐标。--Ext.EventObject
    });//为表格添加双击事件grid.on("itemdblclick",function(grid, row){Ext.Msg.alert("系统提示","你双击啦!ID为:"+row.data.id);  });// 整体架构容器Ext.create("Ext.container.Viewport", {layout : 'border',autoHeight: true,border: false,items : [grid]});
});

 

分析:

1.布局:虽然只有一个子组件grid,但依然采用的是Viewport的布局方式。

 

2.插件

Extjs4.2加了很多拓展插件(4.1版本没有),所在的命名空间为'Ext.ux',如下图:

这里就用到了其中的一个插件:ProgressBarPager--分页进度条,所以在此js需加载此类:

//引入扩展组件
Ext.Loader.setConfig({enabled: true});Ext.Loader.setPath('Ext.ux', '../../ExtJS4.2/ux/');Ext.require(['Ext.data.*','Ext.grid.*','Ext.util.*','Ext.tip.QuickTipManager','Ext.ux.data.PagingMemoryProxy','Ext.ux.ProgressBarPager'
]);

注:除了加载这个 'Ext.ux.ProgressBarPager'插件,对于其他的加载类笔者也不太明白为什么要加载?对于目前的功能,即使注释掉也没影响的,如下:

Ext.require([/*'Ext.data.*','Ext.grid.*','Ext.util.*','Ext.tip.QuickTipManager','Ext.ux.data.PagingMemoryProxy',*/'Ext.ux.ProgressBarPager'
]);

可能是再编辑一些更复杂的功能会需要把。

 

3.xtype: 'rownumberer'

在创建表格时的第一列就创建了'rownumberer'这个对象,在Extjs中,xtype:'..'是很常见的写法,它用于创建某个类的实例(有时没有这个,一般默认的xtype是panel)组件,api解释如下:

 

4.表格的事件

在显示用户数据的表格中涉及了2个事件:

一是某行是否被选中的事件,其定义如下:

    //监听表格(为表格的选择模型添加selectionchange事件)grid.getSelectionModel().on({//getSelectionModel:返回grid的选择模型。on:是addListener的简写方法selectionchange: function(sm, selections) {//一个选项发生改变之后触发。参数:selections:选择的记录if (selections.length) {//如果有被选中的记录,则‘修改用户’、‘删除用户’、‘分配角色’三个按钮设置为可用状态Ext.getCmp('editUser').setDisabled(false);//getCmp:返回指定id的组件Ext.getCmp('delUser').setDisabled(false);Ext.getCmp('allotUser').setDisabled(false);} else {//反之,这三个按钮设置为禁用状态。Ext.getCmp('editUser').setDisabled(true);Ext.getCmp('delUser').setDisabled(true);Ext.getCmp('allotUser').setDisabled(true);}}});

从以上代码可看出,监听表格的某行是否被选中所监听的对象并不是表格本身,而是这个表格所属的选择模型(此表格的选择模型是复选框),在其所属的选择模型上增加‘selectonchange’事件。

 

二是表格的右键菜单事件,如下:

 //表格右键菜单  var contextmenu = new Ext.menu.Menu({  id:'theContextMenu',  items:[{  text:'增加用户',iconCls:'Useradd',handler:function(){  Ext.Msg.alert("系统提示","增加用户");  }  },'-',{  text:'编辑用户',iconCls:'Useredit',handler:function(){  Ext.Msg.alert("系统提示","编辑用户");  }  },'-',{  text:'删除用户',iconCls:'Userdelete',handler:function(){  Ext.Msg.alert("系统提示","删除用户");  }  },'-',{  text:'分配角色',iconCls:'Usergo',handler:function(){  Ext.Msg.alert("系统提示","分配角色");  }  },'-',{  text:'导入',iconCls:'Databasecopy',handler:function(){  Ext.Msg.alert("系统提示","导入");  }  },'-',{  text:'导出',iconCls:'Pagewhiteoffice',menu:{items:[{text:'导出EXCEL',iconCls:'Pageexcel',listeners: {click:function(){Ext.Msg.alert("导出Excel","导出Excel");}}},{text:'导出CSV',iconCls:'Pagegreen',listeners: {click:function(){//Ext.getCmp('editUser').setDisabled(true);Ext.Msg.alert("导出CSV","导出CSV");}}}]}},'-',{  text:'打印',iconCls:'Printer',handler:function(){  Ext.Msg.alert("系统提示","打印");  }  }]  });  //为表格添加右键菜单事件grid.on("itemcontextmenu",function(view,record,item,index,e){ //on:addListener的简写方法. itemcontextmenu:选项的右键菜单事件 右键单击选项时触发。e.preventDefault();  //阻止浏览器默认行为处理事件。--Ext.EventObjectcontextmenu.showAt(e.getXY());  //contextmenu在特定的XY位置显示。 getXY:获取事件的页面坐标。--Ext.EventObject});

从以上代码可看出,在表格中设置右键呼出菜单的功能是先定义菜单项,然后为表格添加监听,其事件就是“itemcontextmenu”。需注意的是,由于在window系统下有自带的右键菜单事件,所以一般都要在处理函数中阻止默认的处理事件。

 

5.一个细节:menu的子组件的xtype默认是panel?

先贴出代码:

                   { xtype: 'button', text: '导出',iconCls:'Pagewhiteoffice',menu:{//菜单属性items:[{//子组件的默认xtype是paneltext:'导出EXCEL',iconCls:'Pageexcel',listeners: {click:function(){Ext.Msg.alert("导出Excel","导出Excel");}}},{text:'导出CSV',iconCls:'Pagegreen',listeners: {click:function(){//Ext.getCmp('editUser').setDisabled(true);Ext.Msg.alert("导出CSV","导出CSV");}}}]}},'-',

以上代码的作用是设置按钮并为它添加菜单——就是menu属性,在button类的api这样介绍此属性:

上面代码中menu的值就是一个菜单对象,它又包含2个子组件,在Ext.menu.Menu的api中解释items说默认的子组件的xtype为panel,如下:

那么其中的text属性应该存在于panel的配置选项中,可是查询没有,在menu中也没有查询到text属性。然后全局查找:

觉得此属性的来源比较靠谱是button类中的此属性——毕竟此菜单的父容器就是button。解释是:按钮里的文字。

现在问题已确定了:items的子组件xtype是默认的panel吗?下面把代码修改成显示的指定xtype为panel,如下:

                       items:[{//子组件的默认xtype是panelxtype:'panel',text:'导出EXCEL',iconCls:'Pageexcel',listeners: {click:function(menu,item){console.log(menu);console.log(item);Ext.Msg.alert("导出Excel","导出Excel");}}}

然后运行,不能正常显示了:

再设置:xtype:'button',

也不能正常显示:

再设置:xtype:'menu',

这一组件直接没了:

最后去掉xtype这个配置,还原,通过调试来看一下是否能确定其身份:

控制台打印的menu的信息如下:

似乎也没有任何迹象表明其身份。所以现在是很奇怪的:items中的两个组件的text属性属于button类;其监听中的click事件属于menu类,那么它自己的xtype到底是什么呢?

 

二、部门管理

执行原理同上,这里直接贴dept.js

//引入扩展组件
Ext.Loader.setConfig({enabled: true});Ext.Loader.setPath('Ext.ux', '../../ExtJS4.2/ux/');Ext.require(['Ext.data.*','Ext.grid.*','Ext.util.*','Ext.tip.QuickTipManager','Ext.ux.data.PagingMemoryProxy','Ext.ux.ProgressBarPager'
]);
Ext.onReady(function() {Ext.define("DeptModel", {extend: "Ext.data.TreeModel",fields: ["id", "text", "status","description"]});var store = Ext.create("Ext.data.TreeStore",{model: "DeptModel",proxy:{  type:'ajax',  url:'../config/treegrid.json' ///dept/showDept
        }});var columns = [{text: '编号',flex: 1,dataIndex: 'id',hidden: true,sortable: true},{xtype: 'treecolumn', //this is so we know which column will show the treetext: '名称',flex: 2,sortable: true,dataIndex: 'text'},{text: '状态',flex: 1,dataIndex: 'status',sortable: true,renderer:function(value){  if(value==0){  return "<span style='color:green;font-weight:bold';>正常</span>";  } else {  return "<span style='color:red;font-weight:bold';>停用</span>";  }}},{text: '描述',flex: 1,dataIndex: 'description',sortable: true}];//var sm = Ext.create('Ext.selection.CheckboxModel');var tree = Ext.create('Ext.tree.Panel', {renderTo: Ext.getBody(),rootVisible: false,region: 'center',//selModel: sm,loadMask:true, //显示遮罩和提示功能,即加载Loading……  columnLines:false, //列的边框border: false,forceFit:true, //自动填满表格 rowLines:true, //设置为false则取消行的框线样式
        columns: columns,store:store});// 整体架构容器Ext.create("Ext.container.Viewport", {layout : 'border',autoHeight: true,border: false,items : [tree]});
});

数据源:treegrid.json

{"text": ".","children": [{"id": "1","text": "总部","status": 0,"expanded": true,"description":"总部根节点","leaf":false,"children": [{"id": "2","text": "开发部","status": 0,"description":"开发部","expanded": true,"children": [{"id": "3","text": "测试部","status": 1,"description":"开发部","leaf": true}, {"id": "4","text": "前端部","status": 0,"description":"开发部","leaf": true}, {"id": "5","text": "质量部","status": 1,"description":"开发部","leaf": true,}, {"id": "6","text": "版本控制部","status": 0,"description":"开发部","leaf": true,}]}, {"id": "7","text": "项目部","status": 1,"description":"开发部","expanded": true,"children": [{"id": "8","text": "实施部","status": 0,"description":"开发部","leaf": true}, {"id": "9","text": "运维部","status": 1,"description":"开发部",leaf:true}]}]},{"id": "10","text": "总部2","status": 0,"expanded": true,"description":"总部根节点","leaf":false,"children": [{"id": "11","text": "开发部2","status": 0,"description":"开发部","expanded": true,"children": [{"id": "12","text": "测试部2","status": 1,"description":"开发部","leaf": true}, {"id": "13","text": "前端部2","status": 0,"description":"开发部","leaf": true}, {"id": "14","text": "质量部2","status": 1,"description":"开发部","leaf": true,}, {"id": "15","text": "版本控制部2","status": 0,"description":"开发部","leaf": true,}]}, {"id": "16","text": "项目部2","status": 1,"description":"开发部","expanded": true,"children": [{"id": "17","text": "实施部2","status": 0,"description":"开发部","leaf": true}, {"id": "18","text": "运维部2","status": 1,"description":"开发部",leaf:true}]}]}]
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据分析 数据清理_数据清理| 数据科学

数据分析 数据清理数据清理 (Data Cleaning) Data cleaning is the way toward altering information to guarantee that it is right, precise, and significant. The definition may be straightforward, yet information cleaning is utilized in numerous situations. Like…

jQuery之call()方法的使用

最近在做项目时候&#xff0c;写了几行关于DOM操作的代码&#xff0c;在方法中使用了this&#xff0c;在后期重构的时候&#xff0c;想将这段分离出来做成一个方法。 最开始想的很简单&#xff0c;就直接分离出来使用方法名称调用即可。 但是实际操作的时候没有效果&#xff0c…

GMTA的完整形式是什么?

GMTA&#xff1a;伟大的思想一致 (GMTA: Great Minds Think Alike) GMTA is an abbreviation of "Great Minds Think Alike". GMTA是“ Great Minds Think Alike”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media…

github的使用

GitHub操作总结 : 总结看不明白就看下面的详细讲解. GitHub操作流程 : 第一次提交 : 方案一 : 本地创建项目根目录, 然后与远程GitHub关联, 之后的操作一样; -- 初始化git仓库 :git init ; -- 提交改变到缓存 :git commit -m description ; -- 本地git仓库关联GitHub仓库 : g…

sql更改完整模式报错_SQL的完整形式是什么?

sql更改完整模式报错SQL&#xff1a;结构化查询语言 (SQL: Structured Query Language) SQL is an abbreviation of Structured Query Language. It is a programming language developed and designed for handling structured data in Relational Database Management System…

基于微服务架构,改造企业核心系统之实践

2019独角兽企业重金招聘Python工程师标准>>> 1. 背景与挑战 随着公司国际化战略的推行以及本土业务的高速发展&#xff0c;后台支撑系统已经不堪重负。在吞吐量、稳定性以及可扩展性上都无法满足日益增长的业务需求。对于每10万元额度的合同&#xff0c;从销售团队…

bkg bnc_BNC的完整形式是什么?

bkg bncBNC&#xff1a;刺刀Neill–Concelman (BNC: Bayonet Neill–Concelman) BNC is an abbreviation of "Bayonet Neill–Concelman". BNC是“刺刀Neill–Concelman”的缩写 。 It is also known as "British Naval Connector" or "Bayonet Nut …

使用visio 提示此UML形状所在的绘图页不是UML模型图的一部分 请问这个问题怎么解决?...

解决方法新建->选择软件与数据库模板->选择UML模型图->注意&#xff1a;如果不选择UML模型图的话&#xff0c;可能会出现无法编辑形状文本&#xff0c;提示“此UML形状所在的绘图页不是UML模型图的一部分&#xff0c;该形状设计用于利用UML模型图模板创建的绘图”关注…

iOS之 开发常用到的宏定义

不久前做过一个小项目种用到了就记录下来方便自己以后使用&#xff0c;一个非常实用的宏定义来打印函数名称等 #ifdef DEBUG #define DebugLog(fmt, ...) NSLog(("\n[文件名:%s]\n""[函数名:%s]\n""[行号:%d] \n" fmt), __FILE__, __FUNCTION__,…

agp模式_AGP的完整形式是什么?

agp模式AGP&#xff1a;加速图形端口 (AGP: Accelerated Graphics Port ) AGP is an abbreviation of the "Accelerated Graphics Port". AGP是“加速图形端口”的缩写 。 It was created and developed as a high-speed point-to-point channel for putting togeth…

XCopy命令实现增量备份

xcopy XCOPY是COPY的扩展&#xff0c;可以把指定的目录连文件和目录结构一并拷贝&#xff0c;但不能拷贝系统文件&#xff1b;使用时源盘符、源目标路径名、源文件名至少指定一个&#xff1b;选用/S时对源目录下及其子目录下的所有文件进行COPY。除非指定/E参数&#xff0c;否则…

dbms_DBMS | 并发控制

dbmsManagement of concurrent transaction execution is known as “Concurrency Control”. Transaction management in DBMS handles all transaction, to ensure serializability and isolation of transaction. DBMS implement concurrency control technique so that the…

ruby 发送post请求_使用Ruby发送电子邮件

ruby 发送post请求Ruby发送电子邮件 (Ruby sending email) Sending emails and routing email among mail servers are handled by Simple Mail Transfer Protocol commonly known as SMTP. Net::SMTP class is a predefined class in Ruby’s library which is purposefully d…

Centos Git1.7.1升级到Git2.2.1

Centos Git1.7.1升级到Git2.2.1安装需求&#xff1a;># yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc ># yum install asciidoc xmlto -y ># yum install gcc perl-ExtUtils-MakeMaker error: /utf8.c:463: undefined r…

tgc 什么意思 tgt_TGT的完整形式是什么?

tgc 什么意思 tgtTGT&#xff1a;训练有素的研究生老师 (TGT: Trained Graduate Teacher) TGT is an abbreviation of Trained Graduate Teacher. It is a title, not a teaching program that is given to a graduate person who has done completion of training in teaching…

svn的使用(Mac)

2019独角兽企业重金招聘Python工程师标准>>> 从服务器下载代码 在终端中输入svn checkout svn://localhost/mycode --username用户名 --password密码 /Users/apple/Documents/code指令意思&#xff1a;将服务器中mycode仓库的内容下载到/Users/apple/Documents/myCo…

scala语言示例_标有示例的Scala关键字

scala语言示例Scala | 任一关键字 (Scala | Either Keyword) Either is a container similar to the option which has two values, they are referred to as children. The left and right children are named as the right child and left child. 这是一个类似于选项的容器&a…

css 中文文字字体_使用CSS的网络字体

css 中文文字字体CSS | 网络字体 (CSS | Web fonts) Web fonts allow people to use fonts that are not pre-installed in their computers. When you want to include a particular font simply include the font file on your browser and it will be downloaded. Web字体允…

Ajax实践之用户是否存在

关于Ajax在之前的学习中&#xff0c;已经对它的基础知识有了初步的了解。仅仅是欠实践。那么接下来就让实践来检验一下真理吧&#xff01; 基础见&#xff1a;http://blog.csdn.net/liu_yujie2011com/article/details/29812777 那么先回忆一下&#xff0c;Ajax是用来解决什么问…

vb 导出整数 科学计数法_可整数组的计数

vb 导出整数 科学计数法Problem statement: 问题陈述&#xff1a; Given two positive integer n and m, find how many arrays of size n that can be formed such that: 给定两个正整数n和m &#xff0c;找出可以形成多少个大小为n的数组&#xff1a; Each element of the …