前段时间公司让我们学习ExtJS,学习了一个礼拜,完成了个小练习,思来想去决定做个总结,但是又懒得敲word,于是就在代码上每行都加上注释,以后忘记了就翻开来看看。
在这里给出代码。
完成的功能如图所示。
1 /** 2 * 默认页面 3 * 4 * @author leaves.qq:1330771552 5 */ 6 7 Ext.define('SupplyManagementDesktop.defaultsWindow', { 8 extend : 'Ext.ux.desktop.Module', 9 10 requires : ['Ext.data.ArrayStore', 'Ext.util.Format', 'Ext.grid.Panel', 11 'Ext.grid.RowNumberer', 'Ext.ux.LiveSearchGridPanel'], 12 13 id : 'defaultsWindow-win', 14 15 /*************************************************************************** 16 * ExtJS控件使用按照如下规则。 首先,创建控件,调用Ext.create 17 * weightName:空间命名空间,args:空间参数,用{}包围,当做对象传入 18 * 19 * ####################################### 注意JS中有如下语法: var object={ 20 * paramter1:value1, paramter2:value2, paramter3:value3 } 21 * object.paramter1可以直接获得value1 ##################################### 22 * 23 * ExtJS中所有空间创建方法都如上 24 * 25 * Ext.create(String weightName,Mixed args) 26 * 所以此处args相当于一个匿名对象(没有引用),但并非真的匿名对象 27 * 28 */ 29 // 初始化窗体的方法 30 init : function() { 31 this.launcher = { 32 text : 'Defaults Window', 33 iconCls : 'icon-grid', 34 // 调用createWindow方法 35 handler : this.createWindow, 36 scope : this 37 // this指向Ext.define(这个方法用来声明命名空间。)定义的命名空间 38 }; 39 },// 初始化窗体的方法结束 40 41 // 创建窗体的方法 42 createWindow : function() { 43 // 下面进行预定义。就好像C里面的 先定义后使用。不然后定义的在前面使用会认为未初始化。(猜测:可能不跟JS一样,属于ExtJS的语法) 44 var dataPanel;// 预定义一个GridPanel,用来显示数据 45 var innerPanel;// 存放Panel的容器 46 var workerPanel; 47 var westPanel; 48 var deptStore; 49 var moduleObj = this;// 创建windows窗体的时获取下本身的环境,此处不能确定,这个this是指向Ext.define还是指向创建的这个窗体 50 var desktop = this.app.getDesktop(); 51 52 // 获取窗体,外部最大窗体,具体方法不清楚。 53 var win = desktop.getWindow('defaultsWindow-win'); 54 55 // 创建按钮bar组件,是上面的几个按钮。 56 var buttonBar = Ext.create('Ext.toolbar.Toolbar', { 57 dock : 'top', 58 items : [{ 59 xtype : 'button', 60 text : '新建', 61 iconCls : 'add', 62 handler : function() { 63 // 自行新建操作,传入一个create字符串用来标示是什么按钮事件,传入dataPanel(注意:上面没有var 64 // dataPanel;此处会报错。)因为后面的新建需要用到表格显示的数据(dataPanel.getSelectionModel().getSelection()) 65 moduleObj.proAction("create", dataPanel, 66 workerPanel); 67 } 68 }, { 69 // 分隔符,不解释。 70 xtype : 'tbseparator' 71 }, { 72 xtype : 'button', 73 text : '删除', 74 iconCls : 'remove', 75 handler : function() { 76 moduleObj.proAction("delete", dataPanel); 77 } 78 }, { 79 xtype : 'tbseparator' 80 }, { 81 xtype : 'button', 82 text : '复制', 83 iconCls : 'copy', 84 handler : function() { 85 moduleObj.proAction("copy", dataPanel, workerPanel); 86 } 87 }, { 88 xtype : 'button', 89 text : '重置检索', 90 iconCls : 'reset', 91 handler : function() { 92 dataPanel.resetSearch(); 93 } 94 }] 95 });// 创建按钮bar组件结束 96 97 // 临时创建的一个用来展示的store 98 var theStore = Ext.create('Ext.data.Store', { 99 fields : [{ 100 name : 'projectId', 101 type : 'String' 102 }, { 103 name : 'projectCode', 104 type : 'String' 105 }, { 106 name : 'projectName', 107 type : 'String' 108 }, { 109 name : 'startDate', 110 type : 'String' 111 }, { 112 name : 'endDate', 113 type : 'string' 114 }, { 115 name : 'qualityTarget', 116 type : 'string' 117 }, { 118 name : 'projectLeader', 119 type : 'string' 120 }, { 121 name : 'projectStatus', 122 type : 'string' 123 }, { 124 name : 'qualification', 125 type : 'string' 126 }, { 127 name : 'constructionUnit', 128 type : 'string' 129 }], 130 pageSize : 20,// 每页显示数量。此处设置可以在向后台申请数据的时候“自动”传参一个 131 // limit和satrt,start不需要指定ExtJS会自动计算,然后传值。 132 proxy : { 133 type : 'ajax',// 使用传输方式为ajax(ajax是异步执行的操作,即不需要刷新页面即可申请后台资源。) 134 method : 'POST',// post和get是HTML中表单(form)提交两种方式,get会在地址栏显示参数,post不显示 135 url : '/Training/myProjectInfoController/getAllProjectInfo.action?deptId=' 136 + 0, 137 138 reader : {// 设置读取方式属性 139 type : 'json',// 设置读取方式格式为:json字符串 140 root : 'root',// 设置根元素,即读取上面fields种的name中对应值的元素,此处多为元素组,json字符串如:{A:a,B:[{},{},{},………………]} 141 totalProperty : 'totalProperty'// 设置总页码 142 } 143 }, 144 autoLoad : true 145 // 自动读取,即显示绑定该store的组件的时候直接读取数据 146 }); 147 // 创建临时Store结束 148 149 // 创建分页bar组建 150 var pagebar = Ext.create('Ext.toolbar.Paging', { 151 pageSize : 20, 152 store : theStore, 153 dock : 'bottom', 154 setActive : false, 155 refresh : false, 156 displayInfo : true, 157 plugins : Ext.create('Ext.ux.ProgressBarPager', {}) 158 }); 159 // 创建分页bar组建结束 160 161 // 为theGirdPanel创建一个SelectionModel 162 var selectionModeltoGridPanel = Ext 163 .create('Ext.selection.CheckboxModel'); // 想要能进行选择或者多选,就需要设置selModel属性这是设置selection的模型,创建一个模型Ext.selection.CheckboxModel 164 // 初始化gridPanel 165 dataPanel = Ext.create('Ext.ux.LiveSearchGridPanel', { 166 title : '<font color=red>工程详细信息</font>', 167 region : 'center', 168 width : '100%', 169 height : '96%', 170 store : theStore, 171 selModel : selectionModeltoGridPanel, 172 // 一系列行,不解释,也可以var column=[`````````]然后columns:column 173 iconCls : 'remove', 174 columns : [{ 175 dataIndex : 'projectId', 176 width : 80, 177 text : '项目号' 178 }, { 179 dataIndex : 'projectCode', 180 width : 80, 181 text : '项目序号' 182 }, { 183 dataIndex : 'projectName', 184 width : 100, 185 text : '项目名称' 186 }, { 187 dataIndex : 'constructionUnit', 188 width : 100, 189 text : '建设单位' 190 }, { 191 dataIndex : 'startDate', 192 width : 80, 193 text : '开工日期' 194 }, { 195 dataIndex : 'endDate', 196 width : 80, 197 text : '竣工日期' 198 }, { 199 dataIndex : 'qualityTarget', 200 width : 100, 201 text : '质量目标' 202 }, { 203 dataIndex : 'projectLeader', 204 width : 100, 205 text : '项目负责人' 206 }, { 207 dataIndex : 'projectStatus', 208 width : 80, 209 text : '项目状态' 210 }, { 211 dataIndex : 'qualification', 212 width : 80, 213 text : '需要资质' 214 }], 215 dockedItems : [buttonBar, pagebar] 216 }); 217 218 // 绑定dataPanel鼠标双击事件。 219 dataPanel.on('itemdblclick', function() { 220 moduleObj.proAction("update", dataPanel, workerPanel); 221 222 }); 223 // 初始化gridPanel结束 224 225 // 为下面的部门信息分类栏(grid)创建一个store数据用jsonu读取/Training/DeptInfoController/getAllDeptInfo.action地址申请到的资源。 226 deptStore = Ext.create('Ext.data.Store', { 227 fields : [{ 228 name : 'deptId', 229 type : 'String' 230 }, { 231 name : 'deptName', 232 type : 'String' 233 }], 234 proxy : { 235 type : 'ajax', 236 method : 'POST', 237 url : '/Training/DeptInfoController/getAllDeptInfo.action', 238 reader : { 239 type : 'json',// 用json字符串 240 root : 'root' 241 } 242 }, 243 autoLoad : true 244 }); 245 246 // 创建部门信息分类栏, 247 workerPanel = Ext.create('Ext.grid.Panel', { 248 title : '部门信息', 249 border : false, 250 store : deptStore, 251 hideHeaders : true, 252 columns : [{ 253 dataIndex : 'deptId', 254 hidden : true, 255 sortable : false, 256 width : 180 257 }, { 258 dataIndex : 'deptName', 259 sortable : false, 260 width : 180 261 }] 262 }); 263 264 // 给部门信息的grid绑定事件,当单击的时候触发事件,此事件用来刷新右侧列表 265 workerPanel.on('itemclick', function(grid, record) { 266 // 获取当前行的deptId列的值 267 var id = record.data.deptId; 268 // dataPanel.store:获取dataPanel的store属性的值,dataPanel.store.proxy获取数据来源属性,ataPanel.store.proxy.url获取数据来源属性的URL, 269 // 这个方法用来重新设置数据来源的地址, 270 // 注意:后面的?deptId是HTML传参方法,地址栏传参。跟form直接传参一样,后台可以接受。 271 dataPanel.store.proxy.url = '/Training/myProjectInfoController/getAllProjectInfo.action?deptId=' 272 + id; 273 dataPanel 274 .setTitle("<font color=red>" 275 + (workerPanel.getSelectionModel().getSelection())[0].data.deptName 276 + "</font>部门信息");// ExtJS中的标题等字符串属性支持HTML语言,直接设置格式。 277 dataPanel.store.load();// dataPanel.store:获取dataPanel的store属性的值,dataPanel.store.load():调用取得的值的load()方法,用来重新加载store数据,实现grid刷新 278 }); 279 280 // 初始工人信息Panel,同下 281 workerPane2 = Ext.create('Ext.grid.Panel', {// Ext.grid.Panel可以直接显示grid的panel不需要create一个Grid放置panel中 282 title : 'BBBBBB',// 随便取标题 283 border : false,// 没有边框 284 store : theStore, 285 hideHeaders : true, 286 columns : [{ 287 dataIndex : 'projectName', 288 sortable : false,// 不能排序 289 width : 180 290 }] 291 }); 292 // 初始工人信息Panel,用来实现折叠效果的panel 293 workerPanel3 = Ext.create('Ext.grid.Panel', {// Ext.grid.Panel可以直接显示grid的panel不需要create一个Grid放置panel中 294 title : 'CCCCCCC',// 随便取标题 295 border : false,// 没有边框 296 store : theStore, 297 hideHeaders : true,// 隐藏grid每列数据的标题 298 columns : [{ 299 dataIndex : 'projectName', 300 sortable : false,// 不能排序 301 width : 180 302 }] 303 }); 304 305 // 左边伸缩栏 306 westPanel = Ext.create("Ext.panel.Panel", { 307 collapsible : true,// 这个属性设置此panel容易可以隐藏(最小化) 308 title : '分类查看', 309 layout : 'accordion',// 这个属性设置此panel容易可以实现折叠效果 310 width : 200, 311 region : 'west', 312 iconCls : 'reset', 313 items : [workerPanel, workerPane2, workerPanel3] 314 // 放置三个小panel容器,如上定义 315 }); 316 317 // 创建容器,用来存放整个窗体的组件,并且在下面直接放置到win中。 318 theContainer = Ext.create('Ext.container.Container', { 319 layout : 'border', 320 items : [dataPanel, westPanel] 321 }); 322 323 // 判断是否已经创建最外边窗体,如果创建了,(JS是弱类型语言,认为null相当于false) 324 if (!win) { 325 win = desktop.createWindow({ // 所以此处的目的是:如果win已经初始化存在了,那么就不新创建窗体,直接调用下面的show()方法 326 // 下面属性不具体解释,详细可以查看API手册 327 id : 'defaultsWindow-win', 328 title : '工程详细信息设置', 329 width : 1100, 330 height : 600, 331 iconCls : 'icon-grid', 332 animCollapse : false, 333 constrainHeader : true, 334 layout : 'fit', 335 items : [theContainer] 336 // 把创建好存放所有组件的窗体放置到外围窗体中 337 }); 338 } 339 win.show();// 显示窗体。 340 return win;// 把窗体的句柄(相当于内存引用)返回 341 }, 342 // 创建窗体的方法结束 343 344 // 显示一个对话框的方法,暂时带有一个用来判断是什么按钮的属性 345 proAction : function(btn, dataPanel, workerPanel) { 346 var selectData;// 预设一个用来存放被选中的数据的变量 347 var innerPanel; 348 // 如果选择的是复制 349 if ("copy" == btn) { 350 if (dataPanel.getSelectionModel().getSelection().length == 0) { 351 Ext.hx.msg("提示", "请先选择您要复制的行"); 352 return; 353 } 354 355 selectData = (dataPanel.getSelectionModel().getSelection())[dataPanel 356 .getSelectionModel().getCount() 357 - 1].data;// 如果是删除的话需要读取被选中的数据,就初始化被selectData。 358 } 359 // 如果选择的是新建 360 if ("create" == btn) { 361 // 新建的时候设置选择的行为null,没有值。也就不会在创建的panel中显示当前行。此处是因为在复制的时候会去读取。 362 selectData = null; 363 } 364 365 // 如果选择的是复制 366 if ("update" == btn) { 367 selectData = (dataPanel.getSelectionModel().getSelection())[0].data;// 先取出所有的记录组成的数组。 368 } 369 370 // 如果选择的是删除 371 if ("delete" == btn) { 372 var oneDate;// 预设一个用来存放一条数据进行操作的变量 373 var records = dataPanel.getSelectionModel().getSelection();// 先取出所有的记录组成的数组。 374 // 判断如果还没有选择任何行就提示并且返回方法 375 if (records.length == 0) { 376 Ext.hx.msg("提示", "请先选择您要删除的行"); 377 return; 378 } 379 380 // 遍历所有的数组然后设置里面的各种标志 381 var array = new Array();// 预设一个用来存放新的data的数组 382 for (var i = 0; i < records.length; i++) { 383 oneDate = records[i].data;// 取出其中一条 384 oneDate.deleteFlg = true;// 设置删除标志 385 array.push(oneDate);// 放置到数组中 386 } 387 388 // 用ajax来进行后台交互 389 Ext.Ajax.request({ 390 url : '/Training/myProjectInfoController/deleteProjectInfo.action', 391 method : 'POST', 392 success : function(res, opts) {// 交互成功的时候 393 Ext.hx.msg("提示", '删除成功!');// 提示 394 dataPanel.store.load();// 表格数据刷新 395 }, 396 failure : function(res, opts) { 397 Ext.hx.msg("提示", '删除失败!'); 398 }, 399 params : { 400 jsonString : Ext.JSON.encode(array) 401 // 调用ExtJS内置对象的方法,把数组转换成json字符串 402 }, 403 scope : this 404 // 作用范围本页。//具体不知道,没用。、 405 }); 406 407 return;// 执行完成操作马上返回,不执行下面代码。 408 } 409 410 /* 下面定义一系列用来输入的文本框 */ 411 deptBoxStore=Ext.create('Ext.data.Store', { 412 fields : [{ 413 name : 'deptId', 414 type : 'String' 415 }, { 416 name : 'deptName', 417 type : 'String' 418 }], 419 proxy : { 420 type : 'ajax', 421 method : 'POST', 422 url : '/Training/DeptInfoController/getAllDeptInfo.action', 423 reader : { 424 type : 'json',// 用json字符串 425 root : 'root' 426 } 427 }, 428 autoLoad : true 429 }); 430 // 下面是一个下来选择菜单,用来下拉选择部门。 431 var dptBox = Ext.create("Ext.form.field.ComboBox", { 432 fieldLabel : '部门选择', 433 store :deptBoxStore , 434 displayField : 'deptName', 435 valueField : 'deptId', 436 allowBlank : false,// 不允许为空 437 editable : false,// 不允许编辑 438 x : 10, 439 y : 20 440 }); 441 //设置上面部门选择的Combox默认值 442 deptBoxStore.load({ 443 callback : function(records) { 444 dptBox.setValue(workerPanel.getSelectionModel().getSelection().length==0?null:(workerPanel.getSelectionModel().getSelection())[0].data.deptId); 445 } 446 }); 447 448 // 各种输入框,制定value(默认值)在没有selectData是null(即if ("create" == 449 // btn)的时候)设置为“”(空字符串),否则分别取出选择行的每一个数据。作为默认数据, 450 var projectIdField = Ext.create('Ext.form.field.Text', { 451 fieldLabel : '项目号', 452 453 x : 10, 454 y : 20, 455 value : selectData != null ? selectData.projectId : "" 456 }); 457 var projectCodeField = Ext.create('Ext.form.field.Text', { 458 fieldLabel : '项目序号', 459 460 x : 10, 461 y : 50, 462 value : selectData != null ? selectData.projectCode : "" 463 }); 464 var projectNameField = Ext.create('Ext.form.field.Text', { 465 fieldLabel : '项目名称', 466 allowBlank : false, 467 blankText : '不可以为空', 468 469 x : 10, 470 y : 80, 471 value : selectData != null ? selectData.projectName : "" 472 }); 473 var constructionUnitField = Ext.create('Ext.form.field.Text', { 474 fieldLabel : '建设单位', 475 476 x : 10, 477 y : 110, 478 value : selectData != null 479 ? selectData.constructionUnit 480 : "" 481 }); 482 var startDateField = Ext.create('Ext.form.field.Date', { 483 format : 'Y-m-d h:m:s ', 484 fieldLabel : '开工日期', 485 blankText : '不可以为空', 486 allowBlank : false, 487 488 x : 10, 489 y : 140, 490 value : selectData != null 491 ? selectData.startDate 492 : new Date() 493 }); 494 var endDateField = Ext.create('Ext.form.field.Date', { 495 format : 'Y-m-d h:m:s ', 496 fieldLabel : '竣工日期', 497 blankText : '不可以为空', 498 allowBlank : false, 499 500 x : 10, 501 y : 170, 502 value : selectData != null 503 ? selectData.endDate 504 : new Date() 505 }); 506 var qualityTargetField = Ext.create('Ext.form.field.Text', { 507 fieldLabel : '质量目标', 508 509 x : 10, 510 y : 200, 511 value : selectData != null ? selectData.qualityTarget : "" 512 }); 513 var projectLeaderField = Ext.create('Ext.form.field.Text', { 514 fieldLabel : '项目负责人', 515 516 x : 10, 517 y : 230, 518 value : selectData != null ? selectData.projectLeader : "" 519 }); 520 var projectStatusField = Ext.create('Ext.form.field.Text', { 521 fieldLabel : '项目状态', 522 523 x : 10, 524 y : 260, 525 value : selectData != null ? selectData.projectStatus : "" 526 }); 527 var qualificationField = Ext.create('Ext.form.field.Text', { 528 fieldLabel : '需要资质', 529 530 x : 10, 531 y : 290, 532 value : selectData != null ? selectData.projectStatus : "" 533 }); 534 535 var submitButton = Ext.create('Ext.button.Button', { 536 text : '确定', 537 x : 10, 538 y : 320, 539 value : selectData != null ? selectData.projectStatus : "", 540 handler : function() { 541 var arr = new Array(); 542 // 上面说道的JS的定义对象的方法, 543 /** 544 * ####################################### 注意JS中有如下语法: var 545 * object={ paramter1:value1, paramter2:value2, paramter3:value3 } 546 * object.paramter1可以直接获得value1 547 * ##################################### 548 */ 549 var data = { 550 projectId : projectIdField.getValue(), 551 projectCode : projectCodeField.getValue(), 552 projectName : projectNameField.getValue(), 553 constructionUnit : constructionUnitField.getValue(), 554 startDate : startDateField.getValue(), 555 endDate : endDateField.getValue(), 556 qualityTarget : qualityTargetField.getValue(), 557 projectLeader : projectLeaderField.getValue(), 558 projectStatus : projectStatusField.getValue(), 559 qualification : qualificationField.getValue(), 560 deptId : dptBox.getValue(), 561 modifyFlg : "update" == btn ? true : false 562 }; 563 564 // 上面定义的data有了projectId,projectCode,······deptId,modifyFlg这些属性,可以直接data.modifyFlg取得值。 565 if (!confirm("确定?")) {// confirm("确定?")弹出对话框,显示确定?点击是的时候返回true,此处判断如果端机否,直接返回方法不执行下面语句。 566 return; 567 } 568 arr.push(data);// 把设置好属性的data对象放置到arr数组中。 569 570 // 用AJAX跟后台交互。 571 Ext.Ajax.request({ 572 url : '/Training/myProjectInfoController/saveProjectInfo.action', 573 params : { 574 jsonString : Ext.JSON.encode(arr) 575 }, 576 success : function(response) { 577 Ext.hx.msg("提示", "成功"); 578 var dialog = Ext.getCmp('theDialog');// Ext.getCmp(String 579 // comID);传入组件ID,返回组件句柄(内存引用) 580 dataPanel.store.load(); // 刷新panel不解释 581 dialog.close();// 把窗体关闭(不显示) 582 dialog.destroy();// 把窗体销毁(清空内存) 583 }, 584 failure : function(response) {// 失败提示 585 Ext.hx.msg("提示", "失败"); 586 } 587 }); 588 } 589 }); 590 var resetButton = Ext.create('Ext.button.Button', { 591 text : '重置', 592 x : 70, 593 y : 320, 594 value : selectData != null ? selectData.projectStatus : "", 595 handler : function() { 596 /* 597 * API上抄来的,不知道什么意思。 up( String selector ) : Container 598 * Walks up the ownerCt axis looking for an ancestor 599 * Container which matches the passed simple selector. 600 */ 601 this.up('form').getForm().reset();// 查找form上面的form(记住这么用吧,说不清楚。仔细看 602 // innerPanel = 603 // Ext.create('Ext.form.Panel', 604 // { 605 // 这句就知道了。)向上找form元素获取form表单,然后重置 606 } 607 }); 608 609 // 创建用来进行输入的文本框数组 610 /** 611 * 此处使用的是Ext.form.Panel目的是为了上面的this.up('form').getForm().reset(); 612 */ 613 innerPanel = Ext.create('Ext.form.Panel', {// 创建一个表单控件, 614 id : 'innerPanel', 615 height : "100%", 616 width : "100%", 617 layout : { 618 type : 'absolute' 619 }, 620 id : 'innerPanel', 621 waitMsgTarget : true,// 显示错误提示的小叹号 622 623 fieldDefaults : { 624 labelWidth : 85, 625 msgTarget : 'side'// 错误提示的字体 626 }, 627 items : [dptBox, projectCodeField, projectNameField, 628 constructionUnitField, startDateField, endDateField, 629 qualityTargetField, projectLeaderField, projectStatusField, 630 qualificationField, submitButton, resetButton] 631 }); 632 633 // 准备好一个用来显示窗体的dialog,实际上是一个窗体 634 var dlalog = Ext.create('Ext.window.Window', { 635 id : 'theDialog', 636 title : '要点击之后显示的窗体', 637 height : 500, 638 width : 300, 639 layout : 'fit', 640 items : [innerPanel], 641 modal : true 642 // 模态窗体,显示的时候不允许操作后面的控件。 643 }); 644 dlalog.show(); 645 } 646 // 显示一个对话框的方法结束 647 });