flex tree实现延时加载
因数据量较大,一下子全部提取上来比较耗时间,所以项目中决定用延时加载,在看的时候 。注意一下initialize、itemOpen事件,还有isBranch、和isLoad属性。搞清楚了这几个重要的东西,基本上就能明白了,下面贴代码
flex代码:
<mx:Tree id="agencyTree"
horizontalScrollPolicy="on"
width="190"
labelField="@name"
height="100%"
scroll="agencyTree_scrollHandler(event)"
dataProvider="{agencyList}"
change="treeChanged(event)"
initialize="agencyTree_initializeHandler(event)"
itemOpen="agencyTree_itemOpenHandler(event)"
click="agencyTree_clickHandler(event)">
</mx:Tree>
复制代码
//获取结构树
public function findAgency_resultHandler(result:ResultEvent):void
{
agencyList=new XML(result.message.body);
if (agencyTree != null)
{
agencyTree.callLater(expandTree);
}
}
复制代码
initialize取得初始化要显示的数据
//调用后台java中的方法(findDistrictsxmlByUser)
districtProxy.findDistrictsxml().addResultListener(findDistricts_resultHandler);
复制代码
findDistrictsxmlByUser代码
public String findDistrictsxmlByUser(User user) throws ServiceException,
SQLException {
String endNode = new String("</node>");
StringBuffer strXML = new StringBuffer();
District district1 = districtDAO.find(District.class, user.getAgency()
.getDistrictId());
strXML.append("<node id='" + district1.getId() + "' name='"
+ district1.getName() + "' level='" + district1.getLevel()
+ "' code='" + district1.getCode() + "' isLoad='" + "true"
+ "' isBranch='" + true + "'>");
List<District> subDistricts = districtDAO.findDistrctByParentId(user
.getAgency().getDistrictId());
District district;
for (int i = 0; i < subDistricts.size(); i++) {
district = subDistricts.get(i);
List<District> districts = districtDAO
.findDistrctByParentId(district.getId());
// 如果有叶子节点isBranch=true ,否则不管
if (districts != null && districts.size() > 0) {
strXML
.append("<node id='" + district.getId() + "' name='"
+ district.getName() + "' level='"
+ district.getLevel() + "' code='"
+ district.getCode() + "' isLoad='" + "false"
+ "' isBranch='" + true + "'>");
} else {
strXML.append(strXMLAppendAddIsLoad(district));
}
strXML.append(endNode);
}
strXML.append(endNode);
return strXML.toString();
}
复制代码
特别注意上边拼字符串中的 isBranch='" + true + "',这个表示当前是非叶子节点,当初为了找这个可是花了些时间,然后里面还有个isLoad属性,先不用管到了后面你就知道了
下面给tree添加一个itemOpen事件agencyTree_itemOpenHandler,即每次打开时候去后台取数据
agencyTree_itemOpenHandler:
private var currentItem:XML;
[Bindable]
//点击机构树节点的时候
protected function agencyTree_itemOpenHandler(event:TreeEvent):void
{
if(event.type == TreeEvent.ITEM_OPEN){
var e:TreeEvent = TreeEvent(event);
currentItem = XML(e.item);
//此时这句话的作用来了,当isLoad为false的时候才去后台去数据,取完之后把isLoad改为true,这样下次点击的时候
//就不会在去取数据了。如果不加这个判断的话 ,每次点开节点的时候都会重复的添加数据
if(currentItem.@isLoad == "false"){
agencyProxy.findAgencyByParentId(currentItem.@id).addResultListener(agencyTree_itemOpenHandler_result);
}
}
}
public function agencyTree_itemOpenHandler_result(event:ResultEvent):void
{
var subAgencyData:XMLList = new XMLList(event.message.body.toString());
// currentItem.appendChild(subAgencyData);//这两种方法都可以,但是下面那种速度快很多
currentItem.node += subAgencyData;
//自动获取树数据超过显示范围时没有自动生成滚动条.好犀利
(agencyTree.dataProvider as XMLListCollection).itemUpdated(currentItem);
(agencyTree.dataProvider as XMLListCollection).dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.ADD, -1, -1, [currentItem]));
currentItem.@isLoad = "true";
}