JSF树动态加载数据的实现

      使用t:tree2(x:tree2同)可以帮我们完成树的展现,但是对于数据量较大(如超过1万条)的树,一次性加载到客户端将很慢,因此通常做法是(这里举例银行机构)初次读取总行及一级分行,当用户想查看某一分行(如浙江行)所辖的二级分行时,再取出浙江行所辖的二级行,这个过程读取和传送的数据量是很小的。

      但是t:tree2本身不提供动态加载数据的功能,而且由于程序员无法捕捉点击+及-事件。但是我们可以试着通过替换树的+和-,并使用自己的+和-以捕捉到用户的请求。具体做法如下:

注意:需要使用x:saveState保存树的状态    

<x:tree2  value="#{deptTreeBean.deptRoot}" id="client-tree" var="node"
   varNodeToggler="t" clientSideToggle="false" showNav="false"
    showLines="false" showRootNode="false">
 <f:facet name="DEPT">
  <h:panelGroup>
   <f:facet name="expand">
   </f:facet>
   <f:facet name="collapse">
   </f:facet>
     <h:panelGrid columns="3" id="panel">
      <h:commandLink immediate="true" οnclick="getId(this.id);" action="#{t.toggleExpanded}"
        rendered="#{!t.nodeExpanded && node.haschild}" actionListener="#{deptTreeBean.findSubUnitBySuperUnitId}">
                 <x:updateActionListener property ="#{deptTreeBean.superUnitTreeNode}" value="#{node}" />
                 <x:graphicImage value="/images/nav-plus.gif" border="0"/>
            </h:commandLink>
            <h:commandLink immediate="true" οnclick="getId(this.id);" action="#{t.toggleExpanded}" rendered="#{t.nodeExpanded && node.haschild}">
                 <x:graphicImage value="/images/nav-minus.gif" border="0"/>
            </h:commandLink>
           
            <h:outputText value="" rendered="#{!node.haschild}" style="width:19px"/>
            <h:panelGroup>
                 <h:commandLink id="link" value=""/>

                 <h:outputText value="#{node.description}" />
             </h:panelGroup>
     </h:panelGrid>
  </h:panelGroup>
 </f:facet>
</x:tree2>

 

如上面代码所示,属性showNav=false时,系统不显示+和-(收缩图标),然后,我们自己将图标放上去,并捕捉点击事件即可。蓝色部分的代码是为了保证子节点相对于父节点有缩进,使得树形结构清晰。

     对应的backingbean代码示例如下:

 

     其中:UnitTreeNode 需要extends TreeNodeBase,且至少增加两个属性:(1)、added属性:boolean,表示该节点是否已经在加载过其子节点。(2)、haschild属性:boolean ,表示是否有子节点

 

 

 /**
 * 部门单选树
 *
 * @author minnanlin88
 *
 */
public class DeptTreeBean extends BaseBean {

 // 部门树根节点
 private UnitTreeNode deptRoot;

 // 点中的节点
 private UnitTreeNode superUnitTreeNode;

 

 

 

  /*  其它代码略 */

 

 

  /**
  * 监听事件:当有节点被展开时,取该节点的所有直接下级子节点
  */
 public String findSubUnitBySuperUnitId(ActionEvent e) {
  try {
   if (superUnitTreeNode != null) {
    // 已经加载过了,不去去数据库
    if (superUnitTreeNode.isAdded()) {
     return null;
    }
   }
   String currDeptId = superUnitTreeNode.getIdentifier().trim();
   // 找到直接下级
   List juniorOrgs = yourService.getDirectSubOrg(
     currDeptId);
   if (juniorOrgs != null && !juniorOrgs.isEmpty()) {
    // 根据需要进行排序
    UnitComparator com = new UnitComparator();
    Collections.sort(juniorOrgs, com);

   

    // 遍历,并将子节点加进来

    Iterator it = juniorOrgs.iterator();

     while (it.hasNext()) {
     Unit unit = (Unit) it.next();
       UnitTreeNode treeNode = new UnitTreeNode("DEPT", unit
        .getUnitId(), unit.getUnitName(), false, "");

      // 置刚加进来的子节点的added值为false,表示他们都没有加载子节点
      treeNode.setAdded(false);
      int sub_count= yourservices.getAllSubCount(unit.getUnitId());
      if (sub_count=0)
       treeNode.setHaschild(false);
      else
       treeNode.setHaschild(true);

     // 添加子节点到树的数据模型中
      this.superUnitTreeNode.getChildren().add(treeNode);

     // 置当前节点已加载过子节点
      this.superUnitTreeNode.setAdded(true);

    }
   }

   if (this.superUnitTreeNode.getChildCount() == 0) {
    this.superUnitTreeNode.setHaschild(false);
   }
  } catch (Exception ex) {
   this.handleException(ex);
  }
  return null;
 } 

}

 

      【另】由于点击后,页面刷新,所以往往在查看位置处在比较底下的分行的所辖二级行时,页面一旦刷新,用户不能定位到该分行,还要再次寻找,造成使用上的不便,因此建议加上自动定位功能(或使用ajax,未验证,不知道可否),这里采用的是再每个节点增加一个链接,点击节点时记录该节点的位置,刷新完后,系统自动重新找到该节点并显示。做法是:

在节点前加上<h:commandLink id="link" value=""/> 系统自动点击link即可定位到该节点,οnclick="getId(this.id);"  的作用就是取得节点的位置,存放在隐藏域里。

 

   页面加载时执行init()方法:

   function init()
  {
      // 自动定位
      var pre_id=document.getElementById("form1:id").value;
      document.getElementById("goto2").href="#"+pre_id+":link";
      document.getElementById("goto2").click();

  }

 

   // 获取ID的前缀,由于JSF的render所产生的id是有规律可循的,如当前树节点的ID是

   //  form1:client-tree:_id25:_id01那么,在其前面的链接link的ID必然为form1:client-tree:_id25:link

  

  function getId(str)
  {
      var arr=str.split(":");
      var newstr="";
      if(arr.length>1)
      {
       for(var i=0;i<arr.length-1;i++)
       {
        if(i==0)
         newstr=arr[i];
        else
            newstr+=":"+arr[i];
       }
      }
      document.getElementById("form1:id").value=newstr;
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值