人使用extjs有大半年的时间,
以下无聊发发,自己封装好的 tree 组件,
扩展的功能有:
1. 搜索过滤树节点(保留结构)
2. 任意指定范围的屏蔽罩
3. 多个树实例的 同步加载时的屏蔽罩,例如拖拽的时候,同步更新数据是个必须的功能。
4. 具有完整的封装及可扩展性。
Java代码
/**
*
* @param {} conf
* @param {} url
*
* @extend isExpandAllNode true 展开全部森林以及子
* @extend maskCfg {scope:xxx,msg:xxx} 屏蔽罩 配置
*
* @extend syncMaskTree 同步屏蔽罩 目标数的引用
* @extend syncAimTree 设置目标同步树的 this['syncMaskTree'] 该属性
* 该属性为 true 则保留开关屏蔽罩逻辑 但不拥有开关权利
*/
TreePanelFil = function(conf, url,params) {
var scope = this;
this['tpStack'] = -1 ;//用于 mask 屏蔽罩的控制 标识树完全展开时 为-1
this['maskLock'] = false ; //用于 mask 屏蔽罩的控制 树还在屏蔽中为 true
/*1.用于 mask 屏蔽罩的控制 为true时 表示该组件被其他 对象同步了屏蔽罩 哪么 开启关闭效果由对方操作
*2.本组件 仍保留 开启关闭 屏蔽罩的逻辑 由this['tpStack'] this['maskLock']两参数体现出
*3.屏蔽罩的 关闭 应由所有
*/
this['syncAimTree'] = false ;
var src = url == null ? '#' : url;
var treeData = new Ext.tree.TreeLoader({
url : src,
requestMethod : 'POST',
baseParams:params
});
var config = {
width : '100%',
split : true,
border : false,
folderSort : true,
autoScroll : true,
loader : treeData,
rootVisible : false,
root : new Ext.tree.AsyncTreeNode({
text : '过滤器类型',
url : src,
expanded : true
})
}
Ext.apply(config, conf);
TreePanelFil.superclass.constructor.call(this, config);
treeData.on('beforeload', function(treeLoader, node) {
if( conf.maskCfg!=null && conf.isExpandAllNode==true ){
scope.startupListenMask(conf.maskCfg);
}
if( conf.maskCfg!=null && conf.isExpandAllNode==false ){
scope.openMask(conf.maskCfg);
}
var id = node.attributes.id;
var para = {id:id};
Ext.apply(treeLoader.baseParams , para);
if( treeLoader.baseParams == null ){
treeLoader.baseParams = para;
}
treeLoader.url = node.attributes.url;
return true;
}, treeData);
treeData.on('load' , function(treeLoader,node,response){
if(conf.isExpandAllNode){
scope.expandNodeAll( scope.getRootNode(),0 );
scope.noteChangeBeforeRoots();
}
if( conf.maskCfg!=null && conf.isExpandAllNode==false ){
scope.closeMask(conf.maskCfg);
}
},treeData);
}
Ext.extend(TreePanelFil, Ext.tree.TreePanel, {
/**
* 重新加载数据
* @param params
*/
reloadData : function(params) {
var scope = this;
var root = this.getRootNode();
var treeLoad = this.getLoader();
if( params!=null )
treeLoad.baseParams = params;
treeLoad.load(root, function(){});
this.expandAll();
},
/**
* @private
* 监听 屏蔽罩 在适当的时候关闭
* 1.在树完全展开后关闭
* @param {} mask
* @param {} msg
*/
startupListenMask : function( maskCfg){
var scope = this;
this['tpStack'] = 0 ;
scope.openMask(maskCfg);
var interval = setInterval(function() {
if ( scope['tpStack'] == -1 ) {
scope.closeMask(maskCfg);
scope['maskLock'] = false;
clearInterval(interval);
}
}, 200);
},
/**
* @private
* 开启屏蔽罩
* @param {} maskCfg
*/
openMask : function(maskCfg){
this['maskLock'] = true;
if( this['syncAimTree']!=true ){
maskCfg.scope.el.mask( maskCfg.msg );
}
},
/**
* @private
* 关闭屏蔽罩
* @param {} maskCfg
*/
closeMask : function(maskCfg){
var scope = this ;
if( scope['syncMaskTree']!=null ){
var interval = setInterval(function() {
if ( scope['syncMaskTree'].isRescindLockMask() ) {
if( this['syncAimTree']!=true ){
maskCfg.scope.el.unmask(true);
}
clearInterval(interval);
}
}, 200);
}else{
if( this['syncAimTree']!=true ){
maskCfg.scope.el.unmask(true);
}
this['maskLock'] = false;
}
},
/**
* @public
* 获取 该树是否已经解除 屏蔽罩
*/
isRescindLockMask : function(){
if( this['tpStack']==-1 && this['maskLock'] == false ){
return true ;
}else{
return false ;
}
},
/**
* @public
* 与其他树组件 同步屏蔽罩
* @param {} tree
* @param {} maskCfg
*/
syncListenMask : function(tree){
this['syncMaskTree'] = tree;
tree.setAmiSynListenMask();
},
/**
* 设置目标同步树的 this['syncMaskTree'] 该属性
* 该属性为 true 则保留开关屏蔽罩逻辑 但不拥有开关权利
*
*/
setAmiSynListenMask : function(){
this['syncAimTree'] = true ;
},
/**
* 展开所有的 节点
*/
expandNodeAll : function(rootNode,index) {
this['tpStack'] = this.setTpStack(index);
var scope = this;
rootNode.expand(true);
var childs = rootNode.childNodes;
for (var i = 0; i < childs.length; i++) {
this['tpStack'] = scope.expandNodeAll(childs[i], (index+1) );
}
this['tpStack'] = this.setTpStack(index);
if( this['tpStack'] == 0 )
this['tpStack'] = -1;
},
setTpStack : function(inx){
var tmp = this['tpStack'];
this['tpStack'] = inx ;
return this['tpStack'];
},
/**
* 过滤显示节点
*
* @param {}
* text
*/
filterNodeByText : function(text) {
var scope = this;
if (this[this.id + 'filterNode'] == null) {
this[this.id + 'filterNode'] = new Ext.tree.TreeFilter(
this, {
clearBlank : true,
autoClear : true
});
}
var filter = this[this.id + 'filterNode'];
this.expandAll();
filter.filterBy(function(n) {
if (text == null)
return true;
if (text == "")
return true;
var str = n.attributes.text;
var newStr = str.substring(0, text.length);
if (newStr == text)
return n;
if (n.childNodes != null && n.childNodes.length > 0) {
return scope.filterParse(n, text);
} else
return false;
});
},
/**
* 该方法必须配合 Ext.tree.TreeFilter 组件使用 递归过滤解析 like 匹配 如果所有子及无限级下级的子
* 没有匹配则返回false
*
* @return 返回
*/
filterParse : function(node, text) {
var str = node.attributes.text;
var newStr = str.substring(0, text.length);
if (newStr == text)
return node;
var nodes = node.childNodes;
if (nodes == null)
return false;
var tNode = null;
for (var i = 0; i < nodes.length; i++) {
if ((tNode = this.filterParse(nodes[i], text))) {
return tNode;
}
}
return false;
}
});
分享到:
相关推荐
总之,`Ext.tree.TreeLoader`与JSON数据的结合使得在Ext JS中创建动态、可扩展的树形视图变得简单高效。通过理解和应用这些概念,开发者能够构建出更加交互丰富的前端应用。希望这个概述能帮助你更深入地了解`...
var tree = Ext.create('Ext.tree.Panel', { renderTo: Ext.getBody(), title: 'TreeGrid', width: 300, height: 150, fields: ['name', 'description'], columns: [ {xtype: 'treecolumn', text: 'Name', ...
源码包含了EXT JS框架的所有核心类和方法,开发者可以通过阅读源码来理解EXT JS内部的工作机制,这对于优化性能、解决兼容性问题或扩展框架功能非常有帮助。 在实际开发中,EXT JS 3.2.0还支持AJAX通信、数据封装...
6. **树形组件和网格**:EXT的`Ext.tree`和`Ext.grid`组件提供了展示和操作树状数据和表格数据的能力。源码中包含了分页、排序、过滤等功能的实现,对于构建数据驱动的应用程序非常有帮助。 7. **工具栏和菜单**:...
7.5.11 树节点:ext.data.nodeinterface与ext.data.tree / 364 7.5.12 store的方法 / 366 7.5.13 store的事件 / 368 7.5.14 store管理器:ext.data.storemanager / 369 7.6 综合实例 / 369 7.6.1 远程读取json...
在EXTJS 中,控件(如面板、按钮等)可以通过扩展这个接口或者使用已封装好的`Ext.dd.DD`和`Ext.dd.DDProxy`类来实现拖放行为。 首先,我们需要为需要拖动的控件实例化一个`DD`对象,传入控件的ID、一个唯一标识和...
总的来说,Ext内容管理系统借助ExtJS的强大功能,为开发者提供了构建高效、可定制化的内容管理解决方案。通过使用预封装的组件和数据管理工具,开发者可以节省大量的时间和精力,专注于内容的创造和管理,而不是底层...
7. **可扩展性**:EXT 3.0 设计为高度可扩展,允许开发者自定义组件、扩展功能,以满足特定项目需求。 EXT 3.0 中文版的CHM文件包含了详细的API文档,以下是其中一些主要部分的概述: - **基础类**:EXT的基础类是...
33. **Ext.data.Tree类**:树形数据结构,用于表示层级关系的数据。 34. **Ext.data.Node类**:树结构中的节点,包含了节点的基本属性和操作。 35. **Ext.Action类**:动作类,用于组合UI组件和事件处理。 36. **...
8. **插件(Plugins)**:插件是扩展组件功能的一种方式,例如Grid的行编辑插件、Tree的拖放插件等,API文档会列出可用的插件及其配置。 9. **表单(Forms)**:Ext3.0提供了丰富的表单元素和表单处理功能,如...
`JsonPluginTreeLoader.js`可能是一个自定义插件,用于扩展`JsonTreeLoader`的功能。在ExtJS中,开发者可以创建自己的插件来增加特定的行为或特性。例如,这个插件可能包含了对异步加载、数据转换或错误处理的增强。...
- **扩展EXT组件**:了解如何根据项目需求自定义或扩展 EXT 提供的标准组件,以满足特定的功能需求。 #### 九、EXT的布局(Layout) - **布局** 是 EXT 中用于定义容器内子元素排列方式的重要概念。EXT 提供了多种...
5. **Function 扩展篇**:EXTJS扩展了JavaScript的函数,提供了如延迟执行、定时执行、创建闭包等高级功能,增强了函数的可重用性和灵活性。 6. **Ext.data.Store**:Store是EXTJS中存储数据的核心组件,它可以连接...
通过深入阅读EXT 2 API文档,开发者不仅可以了解每个组件的属性、方法和事件,还能掌握如何自定义组件、扩展组件以及优化性能。此外,文档中通常还包括示例代码,方便开发者快速上手实践。如果你在下载或理解过程中...
- 为了提高可维护性,应将组件的配置和逻辑封装在自定义扩展(Extension)或组件(Component)中。 综上所述,EXTJS4的下拉菜单树Combobox+Tree组件通过灵活的配置和扩展,可以满足多种应用场景的需求,无论是单选...
10.12 表格与树形的结合——Ext.ux.tree.ColumnTree 第11章 其他布局类简介 11.1 标准布局类 11.1.1 折叠布局——AccordionLayout 11.1.2 边框布局——BorderLayout 11.1.3 卡片式布局——CardLayout 11.1.4 ...
2. **Array 类**:EXTJS扩展了JavaScript的数组对象,添加了一些实用的方法,如Ext.Array.each()用于遍历数组,Ext.Array.indexOf()查找元素的索引。 3. **Number 类**:增强了JavaScript的数字处理,提供了如Ext....
`Ext.grid.EditorGridPanel` 是一个扩展了 `Ext.grid.GridPanel` 的组件,允许直接在表格中编辑数据。它结合了表格视图和表单编辑功能,使得数据编辑变得更加直观。 #### 九、Ext.tree.TreePanel -- 树的使用 **...