Dojo TreeV3使用详解
作者:邓胤(deng.yin@gmail.com)
工作中使用了TreeV3这个dojo的组件,感觉基本上已经是把dojo的treeV3使用到了极点(自定义树的外观,树节点的拖拉,把其他Drag Source拖拉到树中),公司也要求我作个treeV3演说。所以特意把这篇文章写下来。
首先先对treeV3做一个简单的介绍。TreeV3.js, TreeNodeV3.js, .TreeBasicControllerV3.js, TreeContextMenuV3.js,TreeDndControllerV3.js,TreeEditor.js, 主要的就是这些js一起协作。有兴趣的可以看看源码, 其实dojo的代码看起来还算是瞒简单的。下面我就用几个例子来说明怎样扩展或自定义TreeV3。本篇文章是增对有一定dojo知识的读者,如果你现在还不了解dojo,请看
http://dojotoolkit.org/.
1. 为叶子节点增加图标。
IconTree.html
我们在每个TreeNode上加上childIconSrc属性。请看icontree.js怎样让这个属性生效的。
icontree.js
dojo.lang.extend(dojo.widget.TreeNodeV3, {
childIconsrc: "",
childIcon: null,
iconNode:null,
titleNode:null,
postCreate: function(args) {
//build icon
if (args["childIconsrc"]) {
this.childIconsrc = args["childIconsrc"];
}
this.childIcon = document.createElement("img");
if (this.childIconsrc != "") {
this.childIcon.src = this.childIconsrc;
this.childIcon.setAttribute("width", "16");
this.childIcon.setAttribute("height", "16");
}
this.iconNode = this.tree.labelNodeTemplate.cloneNode(true);
this.titleNode = this.tree.labelNodeTemplate.cloneNode(true);
if (!this.isFolder){
//clear treenode, if it is not folder node
this.labelNode.innerHTML="";
}
this.titleNode.innerHTML=this.title;
this.iconNode.appendChild(this.childIcon);
// add icon first, then add title
this.labelNode.appendChild(this.iconNode);
this.labelNode.appendChild(this.titleNode);
}
});
我们扩展了TreeNodeV3这个组件的postCreate方法( dojo组件都有这个方法,他相当于构造方法吧,我们可以在这里做必要的初始化),这里做的事应该比较清楚,我们通过childIconsrc这个属性创建了iconNode,然后清空TreeNodeV3的labelNode。再增加iconNode和titleNode
2. 拖动物体到tree中
dragother.html
Drag me0 to tree.
Drag me1 to tree.
Drag me2 to tree.
You can&apost drag me.
注意黑体的DndAcceptTypes属性。说明这个树接受dragSource type为firstTree或者feed的(也就是自己,还有就是下面的span, 我们需要把span变成可以拖动的物体 dragSource)。再看dragother.js。
dojo.addOnLoad(function(){
var num = 0;
while(dojo.byId("feed_" + num) != null){
var dropSource = new dojo.dnd.HtmlDragSource(dojo.byId("feed_" + num), "feed");
num++;
}
});
dojo.dnd.TreeDropTargetV3.prototype.oldGetDropHandler = dojo.dnd.TreeDropTargetV3.prototype.getDropHandler;
dojo.lang.extend(dojo.dnd.TreeDropTargetV3, {
getDropHandler: function(e, source, targetParent, targetIndex) {
if (source.type == "feed"){
var sourceNode = source.domNode;
if (dojo.widget.byId(sourceNode.id) != null){
alert("this widget has already been here.");
return function(){
return false;
}
}
var node =createTreeNode(sourceNode.id, sourceNode.innerHTML);
targetParent.addChild(node, targetIndex);
return function(){
return true;
}
}
return this.oldGetDropHandler(e, source, targetParent, targetIndex);
}
});
function createTreeNode(widgetId, title) {
return dojo.widget.createWidget("TreeNodeV3",
{
widgetId: widgetId,
title: title,
isFolder: false,
tree: &aposfirstTree&apos
});
}
第一段是让那些span成为dragsource。第二段我们hack了dojo.dnd.TreeDropTargetV3的getDropHandler方法(具体可以看看TreeDndControllerV3.js)。当我们接收到dragSources时我们获取那些span中的一些信息,然后create 一个treeNode,在把这个treeNode加到树中。
3. ...................................................
4. ...................................................
5. ...................................................
还有一些hack treeV3的东西实在不愿写。 dojo的treeV3真的是蛮强大的( 仔细看看那几个**Controller和TreeV3 TreeNodeV3的源码), 而且dojo的widget源码还是蛮容易理解的。有兴趣的朋友可以看看dojo的源码。还有就是dojo包里面tests目录下面的例子。大多数应用的话看看里面的例子也就行了。
例子的源码可以在http://deng.yin.googlepages.com/TreeV3Sample.zip下载。本例子中没有包括dojo0.4源码,用户可以到http://download.dojotoolkit.org/release-0.4.0/dojo-0.4.0-ajax.zip下载源码, 然后解压到例子中的dojo目录。
格式不好的话可以看http://docs.google.com/View?docid=ajgd3tgv958v_3gz374h
工作中使用了TreeV3这个dojo的组件,感觉基本上已经是把dojo的treeV3使用到了极点(自定义树的外观,树节点的拖拉,把其他Drag Source拖拉到树中),公司也要求我作个treeV3演说。所以特意把这篇文章写下来。
首先先对treeV3做一个简单的介绍。TreeV3.js, TreeNodeV3.js, .TreeBasicControllerV3.js, TreeContextMenuV3.js,TreeDndControllerV3.js,TreeEditor.js, 主要的就是这些js一起协作。有兴趣的可以看看源码, 其实dojo的代码看起来还算是瞒简单的。下面我就用几个例子来说明怎样扩展或自定义TreeV3。本篇文章是增对有一定dojo知识的读者,如果你现在还不了解dojo,请看
http://dojotoolkit.org/.
1. 为叶子节点增加图标。
IconTree.html
childIconSrc="images/page.gif" title="Item 1.1" widgetId="Item 1.1">
childIconSrc="images/page.gif" title="Item 1.2" widgetId="Item 1.2">
childIconSrc="images/page.gif" title="Item 2.1" widgetId="Item 2.1">
childIconSrc="images/page.gif" title="Item 4" widgetId="Item 4">
我们在每个TreeNode上加上childIconSrc属性。请看icontree.js怎样让这个属性生效的。
icontree.js
dojo.lang.extend(dojo.widget.TreeNodeV3, {
childIconsrc: "",
childIcon: null,
iconNode:null,
titleNode:null,
postCreate: function(args) {
//build icon
if (args["childIconsrc"]) {
this.childIconsrc = args["childIconsrc"];
}
this.childIcon = document.createElement("img");
if (this.childIconsrc != "") {
this.childIcon.src = this.childIconsrc;
this.childIcon.setAttribute("width", "16");
this.childIcon.setAttribute("height", "16");
}
this.iconNode = this.tree.labelNodeTemplate.cloneNode(true);
this.titleNode = this.tree.labelNodeTemplate.cloneNode(true);
if (!this.isFolder){
//clear treenode, if it is not folder node
this.labelNode.innerHTML="";
}
this.titleNode.innerHTML=this.title;
this.iconNode.appendChild(this.childIcon);
// add icon first, then add title
this.labelNode.appendChild(this.iconNode);
this.labelNode.appendChild(this.titleNode);
}
});
我们扩展了TreeNodeV3这个组件的postCreate方法( dojo组件都有这个方法,他相当于构造方法吧,我们可以在这里做必要的初始化),这里做的事应该比较清楚,我们通过childIconsrc这个属性创建了iconNode,然后清空TreeNodeV3的labelNode。再增加iconNode和titleNode
2. 拖动物体到tree中
dragother.html
DndAcceptTypes="firstTree;feed" widgetId="firstTree" listeners="basicController;
dndcontroller;selector;disableWrap" toggle="fade" showGrid="false" showRootGrid="true">
Drag me0 to tree.
Drag me1 to tree.
Drag me2 to tree.
You can&apost drag me.
注意黑体的DndAcceptTypes属性。说明这个树接受dragSource type为firstTree或者feed的(也就是自己,还有就是下面的span, 我们需要把span变成可以拖动的物体 dragSource)。再看dragother.js。
dojo.addOnLoad(function(){
var num = 0;
while(dojo.byId("feed_" + num) != null){
var dropSource = new dojo.dnd.HtmlDragSource(dojo.byId("feed_" + num), "feed");
num++;
}
});
dojo.dnd.TreeDropTargetV3.prototype.oldGetDropHandler = dojo.dnd.TreeDropTargetV3.prototype.getDropHandler;
dojo.lang.extend(dojo.dnd.TreeDropTargetV3, {
getDropHandler: function(e, source, targetParent, targetIndex) {
if (source.type == "feed"){
var sourceNode = source.domNode;
if (dojo.widget.byId(sourceNode.id) != null){
alert("this widget has already been here.");
return function(){
return false;
}
}
var node =createTreeNode(sourceNode.id, sourceNode.innerHTML);
targetParent.addChild(node, targetIndex);
return function(){
return true;
}
}
return this.oldGetDropHandler(e, source, targetParent, targetIndex);
}
});
function createTreeNode(widgetId, title) {
return dojo.widget.createWidget("TreeNodeV3",
{
widgetId: widgetId,
title: title,
isFolder: false,
tree: &aposfirstTree&apos
});
}
第一段是让那些span成为dragsource。第二段我们hack了dojo.dnd.TreeDropTargetV3的getDropHandler方法(具体可以看看TreeDndControllerV3.js)。当我们接收到dragSources时我们获取那些span中的一些信息,然后create 一个treeNode,在把这个treeNode加到树中。
3. ...................................................
4. ...................................................
5. ...................................................
还有一些hack treeV3的东西实在不愿写。 dojo的treeV3真的是蛮强大的( 仔细看看那几个**Controller和TreeV3 TreeNodeV3的源码), 而且dojo的widget源码还是蛮容易理解的。有兴趣的朋友可以看看dojo的源码。还有就是dojo包里面tests目录下面的例子。大多数应用的话看看里面的例子也就行了。
例子的源码可以在http://deng.yin.googlepages.com/TreeV3Sample.zip下载。本例子中没有包括dojo0.4源码,用户可以到http://download.dojotoolkit.org/release-0.4.0/dojo-0.4.0-ajax.zip下载源码, 然后解压到例子中的dojo目录。
格式不好的话可以看http://docs.google.com/View?docid=ajgd3tgv958v_3gz374h