📄 tree.js
字号:
/*
* Isomorphic SmartClient
* Version 6.5 (2008-04-30)
* Copyright(c) 1998-2007 Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* licensing@smartclient.com
*
* http://smartclient.com/license
*/
//> @class Tree//// A Tree is a data model representing a set of objects linked into a hierarchy.// <P>// A Tree has no visual presentation, it is displayed by a +link{TreeGrid} when supplied as// +link{treeGrid.data}. // <P>// A Tree can be constructed out of a List of objects with interlinked by IDs or via explicitly// specified Arrays of child objects. See +link{attr:Tree.modelType} for an explanation of how// to pass data to a Tree.// <P>// Typical usage is to call +link{treeGrid.fetchData()} to cause automatic creation of a // +link{ResultTree}, which is a type of Tree that automatically handles loading data on // demand. For information on DataBinding Trees, see +link{group:treeDataBinding}.// // @treeLocation Client Reference/System// @visibility external//<isc.ClassFactory.defineClass("Tree", null, "List");//> @groupDef ancestry// Parent/child relationships//<//> @groupDef openList// Managing the list of currently visible nodes based on the open state of parents// <P>// This state may move to the TreeGrid// @visibility internal//<isc.Tree.addClassProperties({//> @type DisplayNodeType//// Flag passed to functions as displayNodeType, telling the function whether it should work on// folders, leaves or both at once.// @group ancestry// @visibility external//// @value null/unset operate on both folders and leavesFOLDERS_AND_LEAVES:null, // @value "folders" operate on folders only, ignoring leavesFOLDERS_ONLY: "folders", // @value "leaves" operate on leaves only, ignoring foldersLEAVES_ONLY: "leaves", //<//> @type LoadState// Trees that dynamically load nodes keep track of whether each node has loaded its children.// // @visibility internal// @group dynamicLoading// @value isc.Tree.UNLOADED not loaded at all (default state)UNLOADED: null, // @value isc.Tree.LOADING currently in the process of loadingLOADING:"loading", // @value isc.Tree.FOLDERS_LOADED folders only are already loadedFOLDERS_LOADED:"folders", // @value isc.Tree.LOADED already fully loadedLOADED:"loaded",//<autoID:0});//// add instance defaults to the tree//isc.Tree.addProperties({ //>@type TreeModelType//// @value "parent" In this model, each node has an ID unique across the whole tree and a// parent ID that points to its parent. The name of the unique ID property is can be specified// via +link{attr:Tree.idField} and the name of the parent ID property can be specified via// +link{attr:Tree.parentIdField}. The initial set of nodes can be passed in as a list to// +link{attr:Tree.data} and also added as a list later via +link{method:Tree.linkNodes}.// Whether or not a given node is a folder is determined by the value of the property specified// by +link{attr:Tree.isFolderProperty}.// <br><br>// The "parent" modelType is best for integrating with relational storage (because nodes can// map easily to rows in a table) and collections of Beans and is the model used for DataBound// trees.//// @value "children" In this model, nodes specify their children as a list of nodes. The// property that holdes the children nodes is determined by +link{attr:Tree.childrenProperty}.// Nodes are not required to have an ID that is unique across the whole tree (in fact, no ID is// required at all). Node names (specified by the +link{attr:Tree.nameProperty}, unique within// their siblings, are optional but not required. Whether or not a given node is a folder is// determined by the presense of the children list (+link{attr:Tree.childrenProperty}).//// @visibility external//<//> @attr tree.modelType (TreeModelType: "children" : IRWA)//// Selects the model used to construct the tree representation. If the "parent" modelType is// used, you can provide the initial parent-linked data set to the tree via the// +link{attr:Tree.data} attribute. If the "children" modelType is used, you can provide the// initial tree structure to the Tree via the +link{attr:Tree.root} attribute.//// @see attr:Tree.data// @see attr:Tree.root//// @visibility external// @example nodeTitles//<modelType: "children",//> @attr tree.isFolderProperty (String: "isFolder": IRW)//// Name of property that defines whether a node is a folder. By default this is set to// +link{TreeNode.isFolder}.//// @see TreeNode.isFolder// @visibility external//<isFolderProperty: "isFolder",//> @attr tree.defaultIsFolder (boolean : null : IR)// Controls whether nodes are assumed to be folders or leaves by default.// <P>// Nodes that have children or have the +link{isFolderProperty} set to true will be considered// folders by default. Other nodes will be considered folders or leaves by default according// to this setting.//// @see treeGrid.loadDataOnDemand// @visibility external//<//> @attr tree.autoSetupParentLinks (boolean : true : IRWA)// true == we should automatically set up links // from nodes to their parents at init() time//// @see tree.init()//<autoSetupParentLinks:true,//> @attr tree.pathDelim (string : "/" : IRWA)//// Specifies the delimiter between node names. The pathDelim is used to construct a unique// path to each node. A path can be obtained for any node by calling// +link{method:Tree.getPath} and can be used to find any node in the tree by calling// +link{method:Tree.find}. Note that you can also hand-construct a path - in other words// you are not required to call +link{method:Tree.getPath} in order to later use// +link{method:Tree.find} to retrieve it.// <br><br>// The pathDelim can be any character or sequence of characters, but must be a unique string// with respect to the text that can appear in the +link{attr:Tree.nameProperty} that's used// for naming the nodes. So for example, if you have the following tree:// <pre>// one// two// three/four// </pre>// Then you will be unable to find the <code>three/four</code> node using// +link{method:Tree.find} if your tree is using the default pathDelim of /.// In such a case, you can use a different pathDelim for the tree. For example if you used |// for the path delim, then you can find the <code>three/four</code> node in the tree above by// calling <code>tree.find("one|two|three/four")</code>.// <br><br>// The pathDelim is used only by +link{method:Tree.getPath} and +link{method:Tree.find} and// does not affect any aspect of the tree structure or other forms of tree navigation (such as// via +link{method:Tree.getChildren}).//// @see attr:Tree.nameProperty// @see method:Tree.find// @visibility external//<pathDelim:"/",// not documented:// parentProperty : always generated, // direct pointer to parent nodetreeProperty : "_isc_tree", // internal property pointing back to the origin tree//> @attr tree.nameProperty (string : "name" : IRW)//// Name of the property that holds the 'name' of a node for the purpose of calculating the path// to the node. By default this is set to +link{TreeNode.name}. If the value of the// nameProperty of a node (e.g. node.name) is not a string, it will be converted to a string by// the Tree via ""+value.//// @see TreeNode.name// @visibility external// @example nodeTitles//< nameProperty:"name",//> @attr tree.titleProperty (string : "title" : IRW)//// Name of the property that holds the title of the node as it should be shown to the user. // By default this is set to +link{TreeNode.title}.//// @visibility external//<titleProperty:"title",//>@attr tree.idField (string : "id" : IRA)//// For trees with modelType "parent", this property specifies the name of the property// that contains the unique ID of nodes in this tree. By default this is set to// +link{TreeNode.id}.//// @see TreeNode.id// @visibility external// @example nodeTitles//<//>@attr tree.parentIdField (string : "parentId" : IRA)//// For trees with modelType "parent", this property specifies the name of the property// that contains the unique parent ID of a node. By default this is set to// +link{TreeNode.parentId}.//// @see TreeNode.parentId// @visibility external// @example nodeTitles//<//> @attr tree.childrenProperty (string : "children" : IRW)//// For trees with the modelType "children", this property specifies the name of the property// that contains the list of children for a node.// // @see attr:Tree.modelType// @visibility external// @example childrenArrays//<childrenProperty:"children",//> @attr tree.openProperty (string : null : IRWA)//// The property the default implementation of +link{Tree.isOpen()} consules to determine if the// node is open or not. By default, this property is auto-generated for you, but you can set// it to a custom value if you want to declaratively specify this state, but be careful - if// you display this Tree in multiple TreeGrids at the same time, the open state will not be// tracked independently - see +link{group:sharingNodes} for more info on this.//// @group openList// @see group:sharingNodes// @visibility external// @example initialData//<//> @attr tree.cacheOpenList (boolean : true : IRWA)// @group openList// If true, we cache the open list and only recalculate it // if the tree has been marked as dirty. If false, we get the openList// every time.//<cacheOpenList:true,//> @attr tree.openListCriteria (string|function : null : IRWA)// @group openList// Criteria for whether or not nodes are included in the openList//<//> @attr tree.data (List of TreeNode : null : IR)//// Optional initial data for the tree. How this data is interpreted depends on this tree's// +link{tree.modelType}.// <P>// If <code>modelType</code> is <code>"parent"</code>, the list that you provide will be passed // to +link{method:Tree.linkNodes}, integrating the nodes into the tree.// <p>// In this case the root node must be supplied separately via +link{Tree.root}, or you may instead provide// the <code>id</code> of the root node via +link{Tree.rootValue}. So for example, to create// this tree:// <pre>// foo// bar// zoo// </pre>// with modelType:"parent", you can do this:// <pre>// Tree.create({// root: {id: "root"},// data: [// {name: "foo", id: "foo", parentId: "root"},// {name: "bar", id: "bar", parentId: "foo"},// {name: "zoo", id: "zoo", parentId: "root"}// });// </pre>// Or this:// <pre>// Tree.create({// rootValue: "root",// data: [// {name: "foo", id: "foo", parentId: "root"},// {name: "bar", id: "bar", parentId: "foo"},// {name: "zoo", id: "zoo", parentId: "root"}// });// </pre>// Specifying the root node explicitly allows you to give it a name, changing the way path// derivation works (see +link{Tree.root} for more on naming the root node).// <P>// For <code>modelType:"children"</code> trees, the data passed in will be assumed to be an // array of children the tree's root node. //// @see attr:Tree.modelType// @see TreeNode// @visibility external// @example nodeTitles//<//> @attr tree.rootValue (string|number : null : IR)//// If you are using the "parent" modelType and did not specify a root node via +link{Tree.root}// with an id (+link{Tree.idField}), then you can provide the root node's id via this property.// See the example in +link{Tree.data} for more info.// // @see Tree.data// @visibility external// @example nodeTitles//<//> @attr tree.root (TreeNode : null : IRW)//// If you're using the "parent" modelType, you can provide the root node configuration via this// property. If you don't provide it, one will be auto-created for you with an empty name.// Read on for a description of what omitting the name property on the root node means for path// derivation.// <p>// If you're using the "children" modelType, you can provide the initial tree data via this// property. So, for example, to construct the following tree:// <pre>// foo// bar// zoo// </pre>// You would initialize the tree as follows: // <pre>// Tree.create({// root: { name:"root", children: [// { name:"foo", children: [// { name: "bar" }// ]},// { name: "zoo" }// ]}// });// </pre>// Note that if you provide a <code>name</code> property for the root node, then the path to// any node underneath it will start with that name. So in the example above, the path to the// <code>bar</code> node would be <code>root/foo/bar</code> (assuming you're using the default// +link{attr:Tree.pathDelim}. If you omit the name attribute on the root node, then it's name// is automatically set to the +link{attr:Tree.pathDelim} value. So in the example above, if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -