博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dojo树使用心得
阅读量:5282 次
发布时间:2019-06-14

本文共 3350 字,大约阅读时间需要 11 分钟。

感谢的投稿,一篇关于dijit.Tree的使用方法介绍,非常好的文章,也很能体现出Dojo的核心设计思想。作为最常用的一个控件,相信这篇文章能帮助到很多同学。再次感谢,为Dojo中文博客带来了第一篇投稿文章:)

概述

Dojo的dijit.tree的代码结构完全遵循MVC结构,结构非常严谨:
M:model使用了dojo基础包提供的dojo.data.itemFileReadStore(只读)或者dojo.data.itemFileWriteStore(可读写)。Tree并不直接使用Store而是通过dijit.tree.TreeStoreModel这个类将sotre和树形结构所需要的结构的进行串接。
V:view就是tree.js中定义的dijit.tree和dijit_TreeNode。这个类主要完成前台的界面渲染,以及树上节点对象之间的管理。
C:_dndSelector.js这个文件名称开始迷惑了我,后来才发现即使不使用拖拽特性,该类中的代码依然会被调用,这个类定义选中节点,删除节点,增加节点,托拽节点的操作。

网上关于tree 的资料根多,而且dojo自身也提供了丰富的样例,这里介绍一些其样例中没有涉及的一些用法。

树的懒加载(lazy load)
其实懒加载本身没什么太多的问题,只是有两点需要说明
图标处理
Dojo对于叶子/非叶子节点的图标处理时会做自动判断。在懒加载时由于有些节点没有加载子节点,dojo在处理这些节点的图标的时候会显示默认的叶子图标,所以这里需要重  新实现treemodel的mayHaveChildren方法,代码如下
var treeModel = new dijit.tree.ForestMode({ ....... }); treeModel.mayHaveChildren = function(item) { //item为对应节点的数据项,该函数返回true表示该节点为非叶子节点,dojo就会为这个节点附着上非叶子图标 if(item.root) { return true; } else { //这里认为初始化树的时候对于每一个节点的数据项中都有type属性,根据属性判断 return (treeModel.store.getValue(item, 'type') != 'xxxx') } }
节点加载
 Dojo树最大的特点就是完全可以靠数据驱动,因此节点的加载,完全可以通过往对应的 父节点的数据项中增加childran实现,参见如如下代码:
var oldExpand = dijit.Tree.prototype._onExpandoClick; dojo.extend(dijit.Tree, { _onExpandoClick: function(message) { var node = message.node; reloadNode(node); oldExpand.apply(this, arguments); } }); function reloadNode(node) { var store = node.tree.model.store; var nodeItem = node.item; //假设我们通过这个方法从后台取得了改node的子节点数据 var dataList = getChildList(); dojo.forEach(dataList, function(x){ ...... x.type = 'yyy'; //以上的代码可以看需要添加,上面一行代码的作用是可以通过store.getValue方法访问该节点对应的item的type属性 store.newItem(x,{parent:nodeItem, attribute: 'children'}); }); }
增加/删除/修改节点
之前已经说过dojo的tree采用了MVC模式,因此上述操作完全可以通过对store的操作实现
1. 增加
上面的懒加载代码已经列出这里不再赘述
2. 修改:
  假设需要修改的节点的treeNode对象实例为node
tree.model.store.setValue(node.item, 'name'/*取决于定义store时的label属性*/, newName)
3. 删除
假设需要删除的节点的treeNode对象实例为node
tree.model.store.deleteItem(node.item)
鼠标函数
上面说了很多,可以发现所有操作都需要获取树节点对应的dojo对象才可以进行。那么这个对象如何获得呢?我们知道对树的操作分为两种,左键点击或者右键菜单,鼠标点中了相对应的节点就可继续往下操作,因此下面介绍如何通过鼠标事件获得节点对象
click
tree.connect(tree, 'onClick', clickTreeNode); function clickTreeNode(item/*点中节点对应的数据项*/, node/*点中的对象,这里node.item就是的第一个参数*/,evt/*事件*/) { ................ }                         
rightClick
右击一般是打开菜单,这里的菜单也是dojo的,因此判断函数为
dojo.connect(pMenu, '_openMyself', function(e){ var node = dijit.getEnclosingWidget(e.target); /*node就是节点对象*/ });
代码选中节点
tree.dndController.setSelection([node])
托拽控制
Dojo的树提供托拽功能,使用托拽功能需要在实例化tree的时候将tree的dndController属性定义为’dijit.tree.dndSource' 。betweenThreshold为0表示不允许同目录下拖动。
实际应用中我们要增加一些限制,这坐介绍两种
i)选中的对象是否允许拖拽
dojo.connect(tree.dndController, 'onMouseDown', function(e){ //如果你的树上有滚动条,请加入如下代码,否则如果你选中了节点后拖动滚动条会出现节点拖拽精灵 if (dijit.getEnclosingWidget(e.target) == tree) { tree.dndController.mousedown = false; return; } //tree.dndController.mousedown为true表示允许拖拽,反之就是不允许,e为鼠标事件对象 //tree的selectedNodes属性可以返回选中的节点列表,这里的代码表示每个选中节点的数据项中的type属性都是xxx才能拖动 tree.dndController.mousedown = dojo.every(tree.selectedNodes, function(node){ return (tree.model.store.getValue(node.item, 'type') == 'xxx') }); });
ii)判断目标节点是否接受正在拖拽的对象
tree.checkItemAcceptance = function(target, source, position) { //target: DomNode 目标节点对应的dom, 用dijit.getEnclosingWidget(target)可以获得TreeNode对象 //source: dijit.tree.dndSource 被拖动的treeNode对象,是一个列表,因为tree允许一次拖动多个节点 //position: 'over', 'before', 'after' //返回true表示允许drop }
                  

转载于:https://www.cnblogs.com/springside6/archive/2012/01/16/2525349.html

你可能感兴趣的文章
vue2.0模拟锚点实现定位平滑滚动
查看>>
oracle 11g 命令 导入 导出表
查看>>
hdu 2766 Equilibrium Mobile
查看>>
2019春总结作业
查看>>
在Chrome Console中加载jQuery
查看>>
浅谈python 手机crash和app crash循环执行问题
查看>>
jQuery左侧菜单实例
查看>>
初识JavaScript
查看>>
计算机的自启动管理
查看>>
[Vue 牛刀小试]:第十二章 - 使用 Vue Router 实现 Vue 中的前端路由控制
查看>>
Nginx 日志文件切割
查看>>
电商网站垮IDC数据备份,MySql主从同步,图片及其它数据文件的同步
查看>>
Lamp环境下设置绑定apache域名
查看>>
.NET Core IdentityServer4实战 第二章-OpenID Connect添加用户认证
查看>>
bzoj 1070 [SCOI2007]修车
查看>>
51nod 1051 最大子矩阵和
查看>>
DL 小记之序
查看>>
iOS Quartz2D矩阵操作
查看>>
C/C++如何整行读入字符串?
查看>>
Python标准库07 信号 (signal包,部分os包)
查看>>