TreeV3等相关导航widget介绍

来源:百度文库 编辑:神马文学网 时间:2024/06/12 11:48:05
1.      TreeV3 & TreeNodeV3
l        简介
TreeV3和TreeNodeV3分别是原有widget的V3版本,其较大地提高了原版本的操作效率及性能。所以在navigation系列的widget中,如果有带V3后缀的版本,应当使用该版本。TreeV3可以看做移个不可见的rootnode,扮演TreeContainer的功能。
l        如何在网页中创建一个TreeV3 widget
有两种方法在一个页面中创建一个TreeV3:
使用makeup标签:

使用编程创建:在页面中的javascript代码中使用dojo.widget.createWidget()方法:
var tree = dojo.widget.createWidget("TreeV3", {listeners:[controller.widgetId]});
var rootNode = dojo.widget.createWidget("TreeNodeV3", {title: "TreeRoot” });
tree.addChild(rootNode);
var node1 = dojo.widget.createWidget("TreeNodeV3", {title: "TreeNode1"});
rootNode.addChild(node1);
var node2 = dojo.widget.createWidget("TreeNodeV3", {title: "TreeNode2"});
rootNode.addChild(node1);

l        加载过程
当页面中包含了一个TreeV3 widget时,在页面加载时该TreeV3的constructor()和initialize()方法会一次被调用,从而创建一个TreeV3对象,并初始化其Template等,如果该tree包含了多个节点,则接下来会多次调用onAfterChangeTree(), 并最后调用onAfterTreeCreate()。
l        一些实用成员变量及方法介绍
addChild()用于为树或者Node节点添加子节点。
TreeV3:
templateCssPath,templateString, makeNodeTemplate(),:用于设置TreeV3widget所用模板文件的路径及名称。
isExpanded, DndMode,createNode( data),makeContainerNodeTemplate(), move( child, newParent, index)
TreeNodeV3:
labelClass, contentClass,expandClass: 各种样式类型;
expandNode, labelNode,nodeDocType, isTreeNode, title, isFolder, addedTo( parent, index,dontPublishEvent), collapse(), destroy(), expand(), setTitle( title)等
从名字即可看出功用,略之,稍后用到再解释。
另外可以查看源代码中的eventNamesDefault数组,其定义了treev3可以抛出的events。
2.      TreeSelectorV3
l        简介
主要用于在其监听的tree上发生了click等事件时,对该click事件的不同情况进行分类处理,并使用publish抛出该select/deselect事件,而对tree及node本身不做任何的操作。
l        加载过程
默认情况下,在TreeSelectorV3.js中通过
定义了该selector监听"afterTreeCreate", "afterCollapse","afterChangeTree",  "afterDetach",  "beforeTreeDestroy"五个事件。例如:当其监听的tree创建后,该tree抛出afterTreeCreate事件,被TreeSelectorV3捕获,并调用onAfterTreeCreate()方法,该方法将tree.domnode的click等事件与TreeSelectorV3的onTreeClick()等方法绑定。
l        TreeClick事件处理过程:
在其监听的treenode上发生了click事件时,对该click事件的不同情况进行相应的select/deselect操作,并使用publish抛出该select/deselect事件,而对tree及node不做任何的操作。所谓的不同onTreeClick事件可分为:
1)       无效点击:点击处不在任何node或其图标上,此时不做任何处理。
2)       点击上次点击的node:onTreeClick()—processNode()— checkSpecialEvent()--  checkRecentClick()— setLastClicked().
3)       点击不同的node时:onTreeClick()—processNode()— deselectIfNoMulti()-- checkSpecialEvent()--  deselectAll()—deselect()—setLastClicked()—select()
4)       双击一个node时:随浏览器不同而略有不同,可查看源码,略之。
l        Select函数:
select: function(node) {
var index = dojo.lang.find(this.selectedNodes, node, true);    if (index >=0 ) {
return; // if the node already selected, return;
}
this.selectedNodes.push(node); // else push the selected node
dojo.event.topic.publish(this.eventNames.select, {node: node} );   // publish the eventNames:select event
},

l        Deselect函数:
deselect: function(node){
var index = dojo.lang.find(this.selectedNodes, node, true);
if (index < 0) {
return; // not selected
}
this.selectedNodes.splice(index, 1); //deselect the node
dojo.event.topic.publish(this.eventNames.deselect,{node: node});
//publish the eventNames:deselect event;
},

3.      TreeBasicControllerV3
l        简介
对于Tree,不加controller,即可实现expand/collapse功能,但是我想是为了更好地贯彻MVC结构(参见摘自dojobook第四章的Tree over structure节),在TreeV3版本中,将这些的control功能从TreeV3(model)中移除,使用controller来实现。
用于TreeV3的Controller主要有三个,其继承关系为TreeBasicController ->TreeLoadingController -> TreeRpcController,他们主要用于对tree进行逻辑控制及定制(树或节点知道该怎样改变及显示其自身,但是对于树及其节点的操作往往还涉及到更高层次的逻辑问题,如expand/collapse以及各节点的包含关系的变动等等,这些就需要controller来控制,这可能跟tree的实现机制有关,它的节点数据都是保存在一个children[]数组中)。而tree并不知道这些controller的存在,这也体现了MVC的设计思想。
我主要研究了TreeBasicController,其他两个较其实现了远程调用的相关功能。
l        加载过程:
同TreeSelectorV3类似,在TreeBasicControllerV3.js中通过:
listenTreeEvents: ["afterSetFolder", "afterTreeCreate", "beforeTreeDestroy"],

定义了该controller默认监听的事件,developer可以通过自行添加。
在其control的tree创建后,其onAfterSetFolder()和onAfterTreeCreate()方法会依次被调用来设置树的展开层次及将自身的方法与tree.domnode点击等事件绑定

l        主要成员变量及方法:
listenTreeEvents:设置该controller监听的事件,默认监听"afterSetFolder", "afterTreeCreate","beforeTreeDestroy"三个事件,可自行添加;
editor, batchExpandTimeout,expandAll( nodeOrTree),expandToLevel( nodeOrTree, level),expand( node),move( child, newParent, ,... index),onAfterSetFolder(message), collapse( node)等等。
l        onTreeClick
当tree被点击时,会出发controller的onTreeClick()方法,一下为处理流程:

l        Expand过程:上图中的expand方法会调用被click的node的expand方法(在TreeNodeV3.js中定义),而node.expand()通过调用viewSetExpand()对该node节点的显示样式进行设置(使用dojo.html.setClass(…,…)方法),然后使用this. showChildren()对展开后的子节点进行显示。
l        Collapse过程:与Expand过程有对应关系,略之。
l        _focusLabel(): 私有方法,用于将节点设置为焦点样式。
4.      Extentions
Extensions are also called plugins, they can be hooked onto widgetsin various combinations and provide wanted options.
Currently there is a couple of extensions
l        TreeDisableWrapExtension
Tree extension, disables wrapping for tree nodes. Also it fixes IEbug when an ‘unwrappable‘ node (e.g single word) will move to next line if nospace left.
l        TreeDocIconExtension
Tree extension, places icon to the left of a node, depening onnodeType property
l        TreeEmphaseOnSelect
Selector extension, highlights currently selected nodes
l        TreeDeselectOnDblselect
Selector extension, deselects a selected node when it is clicked. Usually,one should ctrl-click, or click another node.
l        TreeLinkExtension
Tree extension, turns labels into links, merges object property intotag
5.      Tree Events
There are many classes of events, published with dojo.event.publishmechanism. Every event has a name and message object,containing more precise information about what happened. You may useevents to update your data while tree changes, and to perform additionalprocessing of involved objects.
There is a default naming scheme for an event class. E.g for a treewith widgetId=‘mytree‘, event of class afterTreeCreate will be named"mytree/afterTreeCreate". You may provide other names in eventNamesproperty of the tree.
l        afterTreeCreate
Event occurs after tree creation is complete. There is an alternativeto hook on this action by putting your objects in "listeners"property of the tree. The difference is that listeners are guaranteed to hookbefore nodes get added, and afterTreeCreate is published after Tree widget iscreated.
source
references to tree
l        beforeTreeDestroy
Published right before actual Tree#destroy method is called. Usefulfor cleanups
source
references to tree
l        beforeNodeDestroy
Right before TreeNode#destroy is called. Node is detached after thisevent fired.
source
references to node
l        afterChangeTree
This event is tightly created with node creation process. It isfired when
Ø        a node is created
ü        no parent at this stage
Ø        fires in initialize(), sochildren may be not added yet
ü        a node was moved to anothertree widget
oldTree
references previous tree, null if node has been just created
newTree
new(current) tree
node
target node
l        afterSetFolder
Fires when a node obtains "folder" state. That may happenwhen a first child is added to a leaf, or if a node was initially created with isFolder=true
source
references to node
l        afterUnsetFolder
Fires when a node obtains looses "folder" state. That mayhappen when a last child leaves the node, and Tree.unsetFolderOnEmptyis set, orwhen unsetFolder is called explicitly.
source
references to node
l        (before|after)Move(From|To)
These events share same arguments and fire when a node is moved.Move process is considered something special. When you move a node, nodetach/addChild events get thrown. That allows to tell situations when a nodeleaves a tree for some time (detached then attached) from situations when anode is simply moved to another location
oldParent
previous parent
oldTree
previous tree
oldIndex
previous index among siblings
newParent
new parent
newTree
new tree
newIndex
new index among siblings
child
target node
l        afterAddChild
Published when a node is attached to parent. This may occur at theend of creation process, or when a node is lazily instantiated from dataobject.
Also it occurs when a detached node gets attached.
child
references to node
index
index among siblings
parent
current parent who adopted a child
childWidgetCreated
flag is set if child was laziliy instantiated. That is: it residedas data object in children array, but user expanded its parent, so node widgetcame to life.
l        afterDetach
Occurs when a node is detached. This may happen in the process ofnode destruction. Keep in mind, that detaching a node sets its parent to null,but
tree remains same.
child
references to node
parent
references to old parent
index
references to index among children of old parent
l        after(Expand|Collapse)
Fire when a node is expanded/collapsed. Some togglers do niceanimation hiding/showing node. This event fires when animation finishes.
source
target node
l        afterSetTitle
When a node is edited, or explicit setTitle method is called, thisevent helps to inform interested parts about changes.
source
target node
oldTitle
replaced node title
6.      Tips
l        How to make tree unselectable?
To make tree (or its elements) unselectable usedojo.html.disableSelection in nodeCreate and treeCreate hooks. ApplydisableSelection to every node you want to make unselectable.
How to bind an object to tree node?
There is an "objectId" property and "object"property ready to be filled in from markup or program-way.
l        How to walk all node descendants ?
You may usedojo.lang.forEach(nodeOrTree.getDescendants(),function(elem) { ... }) toprocess all descendants, it will walk children property recursively.
The safer way would be to call TreeCommon.prototype.processDescendants(nodeOrTree,filter, func), it will process all children with func, but will not descendinto nodes if filter(node) returns false. E.g see collapseAll controller methoduses it to collapse all widgets, but skip non-folders and data objects.
l        How to evade a situation where all nodes are (re)moved and tree isempty without a way to add new child (no nodes) ?
Make a single root node withactionsDisabled="DETACH;MOVE". User will be unable to remove it, sointerface will stay sane.
Also, you may want to set actionsDisabled="ADDCHILD" totree itself, so now children can be added besides the root.
l        How to create a custom tree node ?
First, of course, you may explicitly use createSimple for yourwidget and declare your widgetType in markup.
But sometimes, tree has to create a node from data object or justfrom "nothing", e.g in case of createAndEdit.
Then it checks for widgetName property of data object (can benamespaced), and if no widgetName, then tree.defaultChildWidget property shouldcontain node class, e.g mycustom.tree.Node.
Usually, when you override a node, all you need is to adjustdefaultChildWidget,
because widgetName uses generic create and hence works slower rightnow.
l        How to make pages open when a user clicks on node?
There are 2 ways. The first one is to attach TreeSelector and hookon "select" event. So when a user clicks, event handler will changeurl to node.object.href. Of course, you should fill hrefs.
A probably more convinient path would be to employ TreeLinkExtension,which will turn your labelNodes into real links, and apply attrbutes from nodeobject to them.
l        I open very large tree. But navigation away to another page from thetree takes time. What‘s up?
Dojo performs actions not only when a node is created, but alsocleanup when a node is destroyed. Lazy features allow node creation bedistributed in time, but when you navigate away from a large tree, largecleanup causes visible delay. I don‘t know a way to evade that.
l        How to add icons to nodes ?
TreeDocIconExtension handles that. You should declare nodeType foryour nodes, so they‘ll get nodeIcon[Your type] CSS class. Default type isDocument for leaves and Folder for folders.
There is also setNodeTypeClass method to update node CSS when its nodeTypechanges e.g programmatically.
7.      Tree Overall Structure
Sat, 10/07/2006 - 18:26 — ilia
Note: most classes here omitt ‘V3‘ suffix
l        Model + View
The treeitself is a TreeV3 class instance. Hierarchy is maintained in a standardwidgety way: through children[] array. Children are usually TreeNodeV3instances, but you could use your own(overriding?) implementation of course.
TreeV3instance also represents an ‘invisible root‘ node, so it shares common methodswith TreeNodeV3. These methods reside in TreeWithNode mixin.
Modelcontains data and manipulation methods like "addChild","detach" .. etc. It also publishes events when modified.
DOM-structureand view is also merged into model.
Variousfunctionality can be hooked on model‘s events: controller, menu, drag‘n‘dropetc.
Modelevents should help you to integrate tree with application on data-level, so youhook on actual data changes, not the cause (program call, user click etc).
l        Controller
Main controllers are TreeBasicController -> TreeLoadingController-> TreeRpcController
Basically, they are responsible for operating on model andperforming most logic, besides model‘s action. It also makes checks / remotecalls.
Usually, one should work with controller only and let it processmodel.
TreeLoadingController and TreeRpcController are known to performremote calls to server. They use dojo.Deferred and dojo.DeferredList forthat purpose.
Most customizations are also about controller.
And, by the way, model has no idea about its controller... It throwsevents and delivers API to call, that‘s all.
8.   Others
l        Several relating CSS file: treeV3.csswhich define the css class of the tree and it’s node in different states.Another css file TreeDocIcon.css has define the css class of the icon of treeand nodes. You can modify or add some css class according to needed.
l        Note: Part 1-3 of this document is writtenby myself base on my program testing (on the firefox browser), while part 4-7is mainly copied fromdojobook.
l        Example project:
This is the dojoTreeV3 demo which has implement suchfunctions as follow:
i.             AtreeV3 widget can be used to navigate these info displayed in the right-bottompane.
ii.             Asto the tree, its nodes can be added/deleted and expandedToAll with the buttons in the right-top toolbar.
iii.             ThetreeNodes would be emphesized when clicked and expanded/collapsed when doubleclicked.
iv.             Iconsand label’s color of nodes will change dynamically with the state of the tree.
Some functions are achieved by modify theTreeBasicControllerV3.js and I’ll manage later to implement them in a more reasonableapproach as reride the controller by inheriting it.