首页 > 设计 > WEB开发 > 正文

13.5.为控件创建层级数据供应器

2023-07-22 12:39:14
字体:
来源:转载
供稿:网友
13.5.1. 问题
我想用平面对象(对象没有父子关系)表示层级数据,作为DataGrid 的dataProvider。
13.5.2. 解决办法
创建实现IHierarchicalData 接口的自定义数据类,创建方法用于检测是否是节点或对象有父节点以及是否有子节点。
13.5.3. 讨论
IHierarchicalData 接口定义了DataGrid 和AdvancedDataGrid 组件显示层级数据所需的所有方法。层级数据表示的是数据的父子关系。例如各种类型的交通工具—汽车,卡车,轮船—每种里面包含更多类型的交通工具。其中轿车的层次应该是这样:
Figure 13-1.An object hierarchy


下面的就是数据对象表示方式:
+展开
-ActionScript
private var data:Object = [{name:"Vehicles", id:1, parentId:0, type:"parent"},
{name:"Automobiles", id:2, parentId:1, type:"parent"},
{name:"Boats", id:3, parentId:0, type:"parent"},
{name:"Trucks", id:4, parentId:1, type:"parent"},
{name:"Sedans", id:5, parentId:2, type:"parent"}];


这里给每个节点分配一个id 和表示父节点的parentId。这一类型的数据结构一般很难处理。

这里的方法是使用IHierarchicaData 接口;有了它,AdvancedDataGrid 以分组数据显示,Tree控件以数据树显示。IHierarchicalData 接口定义了下列方法:
canHaveChildren(node:Object):Boolean
此方法确定指定的节点是否具有子节点

dispatchEvent(event:Event):Boolean
此方法发出事件

getChildren(node:Object):Object
此方法返回指定节点的所有子节点

getData(node:Object):Object
此方法返回指定节点的搜所有数据,包括子节点

getParent(node:Object):*
此方法返回任意节点的父节点

getRoot():Object
此方法返回层级数据的根节点

hasChildren(node:Object):Boolean
此方法确认指定节点是否具有子节点

下面的ObjectHierarchicalData 类实现了实现上面这些方法:
+展开
-ActionScript
package oreilly.cookbook{
import flash.events.EventDispatcher;
import mx.collections.IHierarchicalData;
public class ObjectHierarchicalData extends EventDispatcher
implements IHierarchicalData
{
private var source:Object;
public function ObjectHierarchicalData(value:Object)
{
super();
source = value;
/* in our simple system, only parents with their type set
to 'parent' can have children; otherwise, they can't have
children */

public function canHaveChildren(node:Object):Boolean
{
if (node.type == "parent") {
return true;
}
return false;
}
/* for any given node, determine whether a node has any
children by looking through all the other nodes for that node's
ID as a parentTask */

public function hasChildren(node:Object):Boolean
{
trace(node.name);
var children:Array = new Array();// = source.parentTask
== parentId);
for each(var obj in source) {
if(obj.parentTask == node.id) {
children.push(obj);
}
}
if (children.length > 0)
return true;
return false;
/* for any given node, return all the nodes that are
children of that node in an array */

public function getChildren(node:Object):Object
{
var parentId:String = node.id;
var children:Array = new Array();
for each(var obj in source) {
if(obj.parentTask == parentId) {
children.push(obj);
}
}
return children;
}
public function getData(node:Object):Object
{
for each(var obj in source) {
for(var prop in node) {
if(obj[prop] == node[prop]) {
return obj;
else {
break;
}
}
}
return null;
/* we want to return every obj that is a
root object
which, in this case, is going to be all nodes that have a
parent node of '0' */

public function getRoot():Object
{
var rootsArr:Array = new Array();
for each(var obj in source) {
if(obj.parentTask == "0") {
rootsArr.push(obj);
}
}
return rootsArr;
}
public function getParent(node:Object):*
{
for each(var obj in source) {
if(obj.parentTask == node.parentTask) {
return obj;
}
}
return null;
}
}
}

现在这些方法都能确定数据对象中所有节点之间的关系。你可以建立一个新的层级数据类给AdvancedDataGrid 的dataProvider。使得控件能正确显示层级数据。
+展开
-XML
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxmlwidth="400"
height="300creationComplete="init()">

<mx:Script>
<![CDATA[
import mx.collections.*;
[Bindable]
private var ohd:ObjectHierarchicalData;
/* here'sthehugeobjectthatwe're going to use to
populate our ObjectHierarchicalData object */

private var largeObject:Object =
[{
"id":"1""name":"Misc""type":"parent",
"parentTask":"0"},
{"id":"2""name":"Clean the kitchen""type":"parent",
"parentTask":"0"},
{"id":"3""name":"Pay the bills""type":"parent",
"parentTask":"0"},
{"id":"4""name":"Paint the shed""type":"parent",
"parentTask":"1"},
{"id":"5""name":"Get ready for party",
"type":"parent",
"parentTask":"1"},
{"id":"6""name":"Do the dishes""type":"child",
"parentTask":"2"},
{"id":"7""name":"Take out trash""type":"child",
"parentTask":"2"},
{"id":"8""name":"Gas Bill""type":"child",
"parentTask":"3"},
{"id":"9""name":"Registration""type":"child",
"parentTask":"3"},
{"id":"10""name":"Fix the car""type":"parent",
"parentTask":"0"},
{"id":"11""name":"New tires""type":"child",
"parentTask":"10"},
{"id":"12""name":"Emissions test""type":"child",
"parentTask":"10"},
{"id":"13""name":"Get new paint""type":"child",
"parentTask":"4"},
{"id":"14""name":"Buy brushes""type":"child",
"parentTask":"4"},
{"id":"15""name":"Buy Drinks""type":"child",
"parentTask":"5"},
{"id":"16""name":"clean living room""type":"child",
"parentTask":"5"},
{"id":"16""name":"finish invitations""type":"child",
"parentTask":"5"} ];
private function init():void {
ohd = new ObjectHierarchicalData(largeObject);
}

]]>
</mx:Script>
<mx:AdvancedDataGrid dataProvider="{ohd}width="300"
height="200">

<mx:columns>
<!-- all we want to display of the object is the name,
the ADG will take care of displaying the parent child
relationship 
-->

<mx:AdvancedDataGridColumn dataField="name"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Canvas>
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表