花了3-4个小时整了一个有关ExtJS5的TreePanel组件的节点增删改查操作以及拖拽排序的demo,demo里仅仅是前端操作,不涉及后台代码。因为TreePanel是ExtJS里使用难度稍微大点的一个组件之一,特此写这篇文章记录一下,也希望能给那些对ExtJS同样感兴趣的童鞋们一些帮助。
-
- Ext.define("OA.view.TreePanel",{
- extend:'Ext.tree.Panel',
- alias : 'widget.mytreepanel',
- alternateClassName: ["OA.TreePanel"],
- initComponent : function(){
- Ext.apply(this,{
- title:"导航菜单",
- animate:true,
- animCollapse: true,
- autoScroll : true,
- scroll: "vertical",
- rootVisible : false,
- lines: false,
- useArrows: true,
- containerScroll: true,
- collapsed: false,
- collapsible: false,
- layout: "fit",
- border: false,
- width: 200,
- dockedItems: {
- dock : 'top',
- xtype : 'toolbar',
- items : [
- {
- xtype : 'button',
- text : '刷新'
- },
- {
- xtype : 'button',
- text : '展开'
- },
- {
- xtype : 'button',
- text : '收缩'
- }
- ]
- },
- viewConfig : {
- loadingText : "正在加载...",
- plugins: {
- ptype: 'treeviewdragdrop'
- },
- listeners: {
- drop: function(node, data, dropRec, dropPosition) {
-
- }
- }
- },
- store: Ext.create("OA.store.TreeStore")
- });
- this.callParent(arguments);
- }
- });
plugins: {
ptype: 'treeviewdragdrop'
},
这里是给TreePanel添加拖拽插件的,从而支持通过鼠标拖拽节点实现节点排序,添加此插件仅仅是实现了前端界面上的排序效果,要达到真正的排序还是需要借助后台代码来实现的。比如拖拽后在drop事件里,去请求后台处理,具体逻辑就是把被拖拽节点从其原始父节点里删除,将其父节点设置为当前投放的节点。
-
- Ext.define("OA.store.TreeStore", {
- extend : "Ext.data.TreeStore",
- requires: ['OA.util.AppUtil'],
- model: 'OA.model.TreeModel',
- singleton: false,
- root: {
- id: 0,
- expanded: true,
- children: [
- {
- id: 1,
- text: "系统管理",
- leaf: true
- },
- {
- id: 2,
- text: "订单管理",
- leaf: true
- },
- {
- id: 3,
- text: "流程管理",
- leaf: true
- }
- ]
- },
- clearOnLoad : true,
- nodeParam: "id"
- });
TreePanel的数据源类里直接定义了数据,没有从后台加载数据,为了演示方便,不想弄的太麻烦。如果想弄成从后台动态加载数据,可以配置api,比如:
- proxy: {
- type: 'ajax',
- api: {
- create: 'xxxxxxxxxxxxxxx/tree/add',
- read: 'xxxxxxxxxxxxxxxxx/tree/list',
- update: 'xxxxxxxxxxxxxxx/tree/edit',
- destroy: 'xxxxxxxxxxxxxx/tree/delete'
- },
- writer: {
- type: 'json',
- allowSingle: false,
- encode: true,
- root: 'records'
- }
- },
create即添加请求,read即查询请求,update即修改请求,destory即删除请求。
分别对应各自的后台请求URL,你懂的。
-
- Ext.define("OA.model.TreeModel", {
- extend : "Ext.data.Model",
- fields : [
- {name : "id",type : "int"},
- {name : "text",type : "string"},
- {name : "leaf",type : "boolean"},
- {name : "expanded",type : "boolean"}
- ]
- });
TreePanel需要的数据模型,text即节点名称,leaf即是否为叶子节点,expanded即默认是否展开,如果你希望在节点前面加一个小图标,那么你还可以在数据模型再加一个属性iconCls,给它赋值一个css样式即可。
-
- Ext.define("OA.view.TreeContextMenu",{
- extend: 'Ext.menu.Menu',
- alias : 'widget.treecontextmenu',
- alternateClassName: ["OA.TreeContextMenu"],
- initComponent: function(){
- Ext.apply(this,{
- floating :true,
- plain : true,
- floating:true,
- items :[
- {
- itemId: 'add',
- text : '添加'
- },
- {
- itemId: 'edit',
- text : '编辑'
- },
- {
- itemId: 'delete',
- text : '删除'
- }
- ]
- });
- this.callParent(arguments);
- }
- });
这是一个右键菜单,没什么好说的
-
- Ext.define("OA.view.TreeEditWindow",{
- extend: 'Ext.window.Window',
- alias : 'widget.treeeditwindow',
- alternateClassName: ["OA.TreeEditWindow"],
- initComponent: function(){
- Ext.apply(this,{
- title: "编辑节点",
- width: 230,
- height: 100,
- layout: "fit",
- closeAction: "hide",
- items :[
- {
- xtype: "form",
- defaultType: 'textfield',
- defaults: {
- anchor: '100%'
- },
- fieldDefaults: {
- labelWidth: 60,
- labelAlign: "left",
- flex: 1,
- margin: 5
- },
- items: [
- {
- xtype: "textfield",
- name: "nodeName",
- fieldLabel: "节点名称",
- allowBlank: false
- }
- ]
- }
- ],
- buttons: [
- { xtype: "button", itemId: "ok",text: "确定"},
- { xtype: "button", itemId: "cancle", text: "取消"}
- ]
- });
- this.callParent(arguments);
- }
- });
这是一个普普通通的Window,点击菜单里的编辑,即创建窗体对象并show出来。
其实主要的事件处理逻辑都写在Controller里,代码如下:
-
-
-
- Ext.require(
- [
- 'OA.util.CommonDoActionUtil'
- ]
- );
-
- Ext.define('OA.controller.AppController', {
- extend: 'Ext.app.Controller',
- requires: ['OA.util.CommonDoActionUtil'],
-
- models: [
- 'TreeModel'
- ],
-
- views: ["TreePanel","TreeContextMenu","TreeEditWindow"],
-
- stores: [
- 'TreeStore'
- ],
- init: function() {
- var id_ = 111;
- var currentRecord = null;
- this.control({
- "mytreepanel": {
- itemcontextmenu: function(_this, record, item, index, evt, eOpts) {
- if(!this.ctxMenu) {
- this.ctxMenu = Ext.create("OA.view.TreeContextMenu");
- }
- this.ctxMenu.showAt(evt.getXY());
-
- currentRecord = record;
- evt.preventDefault();
-
- _this.getSelectionModel().select(index);
- },
- containerclick: function(_this,e,eOpts) {
- if(this.ctxMenu) {
- this.ctxMenu.hide();
- }
- }
- },
- "treecontextmenu > menuitem[itemId=add]": {
- click: function(item, event, eOpts) {
- if(currentRecord) {
- currentRecord.appendChild(
- {
- id: id_++,
- "text": "测试节点_" + id_,
- "leaf": true
- }
- );
-
- currentRecord.expand();
-
- }
- }
- },
- "treecontextmenu > menuitem[itemId=edit]": {
- click: function(item, event, eOpts) {
- if(currentRecord) {
- if(!this.editWin) {
- this.editWin = Ext.create("OA.view.TreeEditWindow");
- }
- this.editWin.show();
- }
- }
- },
- "treecontextmenu > menuitem[itemId=delete]": {
- click: function(item, event, eOpts) {
- if(currentRecord) {
- currentRecord.parentNode.removeChild(currentRecord);
- currentRecord.commit();
- }
- }
- },
- "treeeditwindow button[itemId=ok]": {
- click: function(_this, e, eOpts ) {
- if(currentRecord) {
-
- var formData = _this.up("treeeditwindow").down("form").getForm().getValues();
- var nodeText = formData.nodeName;
-
- currentRecord.set("text",nodeText);
- currentRecord.commit();
-
- }
-
- _this.up("treeeditwindow").hide();
- }
- },
- "treeeditwindow button[itemId=cancle]": {
- click: function(_this, e, eOpts ) {
- _this.up("treeeditwindow").hide();
- }
- }
- });
- this.commonAction = Ext.create('OA.util.CommonDoActionUtil');
- }
- });
最后效果图如下:
各位看官如果还有什么疑问或者需要demo源码的,请加我QQ:7-3-6-0-3-1-3-0-5,或者加裙
转载:http://iamyida.iteye.com/blog/2192311