分享

一份完整的Spring Hibernate DWR extJs的生成树及下拉comBobo...

 昵称72617 2008-10-14
在各种论坛上看了很久,没见到完整extJs树的生成代码。研究了很久终于实现了Spring+Hibernate+DWR+extJs的生成树及下拉comBoboxTree。
     不敢独享收获 ,借javaeye这一平台将我的成果和大家分享。不足和错误之处敬请批评指正。有疑问欢迎联系我。qq:446702119 msn: wh_aq@hotmail.com
     

     废话少说,还是从生成树开始吧。
     一、树的对象模型。
        
Java代码 复制代码
  1. package com.ssgly.model;   
  2.   
  3. import java.util.List;   
  4. import java.util.Set;   
  5.   
  6.     
  7. public class Region {   
  8.     
  9.     private Long id;   
  10.     private String name;   
  11.     private String code;   
  12.     private Region parent;   
  13.     private Set<Region> children = new java.util.HashSet<Region>();   
  14.   
  15.     public Region() {}   
  16.   
  17.     public Region(String name, String code, Region parent) {   
  18.         this.name = name;   
  19.         this.code = code;   
  20.         if(parent!=null) parent.addChild(this);        
  21.     }   
  22.   
  23.     public Long getId() {   
  24.         return id;   
  25.     }   
  26.   
  27.     public void setId(Long id) {   
  28.         this.id = id;   
  29.     }   
  30.   
  31.     public String getName() {   
  32.         return name;   
  33.     }   
  34.   
  35.     public void setName(String name) {   
  36.         this.name = name;   
  37.     }   
  38.   
  39.     public String getCode() {   
  40.         return code;   
  41.     }   
  42.   
  43.     public void setCode(String code) {   
  44.         this.code = code;   
  45.     }   
  46.   
  47.     public Region getParent() {   
  48.         return parent;   
  49.     }   
  50.   
  51.     public void setParent(Region parent) {   
  52.         this.parent = parent;   
  53.     }   
  54.   
  55.     public Set<Region> getChildren() {   
  56.         return children;   
  57.     }   
  58.   
  59.     public void setChildren(Set<Region> children) {   
  60.         this.children = children;   
  61.     }   
  62.         
  63.   
  64. }   
  65.            

二、树结构的数据库(mySql)DDL
Java代码 复制代码
  1. CREATE TABLE `region` (   
  2.   `id` bigint(20) NOT NULL,   
  3.   `name` varchar(100default NULL,   
  4.   `code` varchar(100default NULL,   
  5.   `parent_id` bigint(20default NULL,   
  6.   PRIMARY KEY  (`id`),   
  7.   KEY `FK91AD1314568C1D72` (`parent_id`),   
  8.   CONSTRAINT `FK91AD1314568C1D72` FOREIGN KEY (`parent_id`) REFERENCES `region` (`id`)   
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

三、对象模型到数据库的Hibernate映射关系
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate./hibernate-mapping-3.0.dtd">   
  4. <hibernate-mapping>   
  5.         
  6.     <class name="com.ssgly.model.Region" table="region"  >   
  7.         <id       name="id"   column="id"  type="java.lang.Long">   
  8.              <generator class="assigned" />   
  9.         </id>           
  10.         <property name="code" column="code" type="java.lang.String" />   
  11.         <property name="name" column="name"  type="java.lang.String"  />   
  12.         <many-to-one name="parent"   column="parent_id"    cascade="save-update"  />   
  13.         <set name="children"   inverse="true" cascade="save-update"  lazy="false">   
  14.              <key column="parent_id"  ></key>   
  15.              <one-to-many class="com.ssgly.model.Region"></one-to-many>   
  16.         </set>   
  17.     </class>   
  18. </hibernate-mapping>  

四、用Spring框架来管理和支撑持久层、业务逻辑层和展示层
【一】持久层采用了DAO模式 。具体设计了一个类型安全的泛型DAO。由于这不是我要讲的重点部分,感兴趣的朋友可以
查阅有关文档。要生成一个树,必须要从后台数据库中按一定类型(我用了适配器模式)取出java对象--TreeNode 对象  。及要实现方法 public List<Region> listRegionByParent(Region parent)。
TreeNode类型为:
Java代码 复制代码
  1. package com.ssgly.model;   
  2.   
  3.   
  4.   
  5. ublic  class TreeNode {   
  6. private String id;   
  7. private String Text;   
  8. private boolean leaf;   
  9. private String cls="";    
  10.   
  11. private Region region;   
  12.   
  13. public TreeNode(Region region)   
  14. {   
  15.         this.region=region;   
  16. }      
  17.   
  18. public String getId() {        
  19.         return region.getId().toString();   
  20. }   
  21.     
  22. public boolean getLeaf() {         
  23.         return region.getChildren().size()<1;   
  24. }          
  25.   
  26. public String getText() {              
  27.         return region.getName();   
  28. }   
  29.   
  30. public String getCls() {   
  31.     return region.getChildren().size()<1?"file":"folder";   
  32. }   
  33.   
  34.     
  35.   
  36.     


具体生成树的泛型DAO实现是:
Java代码 复制代码
  1. package com.ssgly.dao;   
  2.   
  3.     
  4.   
  5. import java.io.IOException;   
  6. import java.sql.SQLException;   
  7. import java.text.SimpleDateFormat;   
  8. import java.util.List;   
  9.   
  10. import com.ssgly.model.Region;   
  11.   
  12. import com.ssgly.model.Page;   
  13.   
  14.   
  15. public class RegionDAOImpl extends GenericHibernateDAOCrud<Region> implements IRegionDAO {   
  16.        
  17.     public RegionDAOImpl(){   
  18.            
  19.         super(Region.class);   
  20.     }   
  21.   
  22.     public void deleteRegion(Region region) {   
  23.         hibernateTemplate.delete(region);   
  24.            
  25.     }   
  26.   
  27.     public void deleteRegion(Long id) {   
  28.         hibernateTemplate.delete(hibernateTemplate.get(Region.class, id));   
  29.            
  30.     }   
  31.   
  32.     public Region getRegion(Long id) {   
  33.             
  34.         return (Region)hibernateTemplate.get(Region.class, id);   
  35.     }   
  36.   
  37.     public Long saveRegion(Region region) {   
  38.         hibernateTemplate.save(region);   
  39.         return region.getId();   
  40.     }   
  41.   
  42.     public void updateRegion(Region region) {   
  43.            
  44.         hibernateTemplate.saveOrUpdate(region);   
  45.     }   
  46.        
  47.     /**  
  48.      * 查询父节点的所有子节点  
  49.      * @param parent   父节点  
  50.      * @return  该父节点对应的子节点  
  51.      *   
  52.      *   
  53.      **/  
  54.     public List<Region> listRegionByParent(Region parent) {   
  55.          if (parent==null){   
  56.              return (List<Region>)hibernateTemplate.find("from Region as r where r.parent is null");    
  57.          }else{   
  58.              return (List<Region>)queryForLists("from Region as r where r.parent=?"  
  59.                          ,new Object[]{parent});   
  60.                 
  61.          }   
  62.            
  63.     }   
  64.   
  65.        
  66. }  


从上面java代码中可以看到:DWR需要解析的是 List<Region> 类型的对象。
【二】业务逻辑层主要采用一个实现类BusinessServiceImp 。将所有的业务逻辑放在一个类中,一是便于spring中bean好管理,二是方便权限控制。BusinessServiceImp 中的一个很重要的属性是: private IRegionDAO regionDAO; regionDAO的生命周期依赖于spring容器,在spring中管理和维护。逻辑层的代码如下:
Java代码 复制代码
  1. package com.ssgly.business.impl;   
  2.   
  3. import java.io.IOException;   
  4. import java.io.Serializable;   
  5. import java.sql.SQLException;   
  6. import java.util.ArrayList;   
  7. import java.util.Iterator;   
  8. import java.util.List;   
  9.   
  10. import com.ssgly.model.*;   
  11. import com.ssgly.util.Hzxs;   
  12.   
  13. import com.ssgly.business.BusinessService;   
  14. import com.ssgly.dao.*;   
  15.   
  16.   
  17. public class BusinessServiceImpl implements BusinessService {   
  18.         
  19.         private IRegionDAO regionDAO;   
  20.            
  21.         public void setRegionDAO(IRegionDAO regionDAO) {   
  22.             this.regionDAO = regionDAO;   
  23.         }   
  24.         
  25.         public List<TreeNode> getAllChildren(Long parentId) throws IOException,   
  26.                 SQLException {   
  27.             List<Region> listRegion=regionDAO.listRegionByParent(regionDAO.getRegion(parentId));   
  28.             List<TreeNode> listTreeNode=new ArrayList<TreeNode>();   
  29.             for(Region region:listRegion){   
  30.                 System.out.println(">>"+region.getName());   
  31.                 listTreeNode.add(new TreeNode(region));   
  32.             }   
  33.             //System.out.println("List<TreeNode> getAllChildren 方法已执行!");   
  34.             return listTreeNode;   
  35.         }   
  36.             
  37.            
  38. }  

【三】Spring容器的配置主要是通过xml方式体现。
一是:web.xml的配置如下:
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  3.     "http://java./dtd/web-app_2_3.dtd">   
  4. <web-app>   
  5.    <context-param>   
  6.         <param-name>contextConfigLocation</param-name>   
  7.         <param-value>   
  8.             /WEB-INF/dispatcherServlet-servlet.xml,   
  9.             /WEB-INF/model-config.xml               
  10.         </param-value>   
  11.     </context-param>   
  12.   <!-- log4j config -->   
  13.     <context-param>   
  14.         <param-name>log4jConfigLocation</param-name>   
  15.         <param-value>/WEB-INF/log4j.properties</param-value>   
  16.     </context-param>      
  17.  <!--========================================================================   
  18.         Filters   
  19.     =========================================================================-->   
  20.   
  21.     <filter>   
  22.         <filter-name>encodingFilter</filter-name>   
  23.         <filter-class>com.ssgly.web.filter.EncodingFilter</filter-class>   
  24.         <init-param>   
  25.             <param-name>encoding</param-name>   
  26.             <param-value>utf-8</param-value>   
  27.         </init-param>   
  28.     </filter>   
  29.     <filter-mapping>   
  30.         <filter-name>encodingFilter</filter-name>   
  31.         <url-pattern>*</url-pattern>   
  32.     </filter-mapping>       
  33.  <!--========================================================================   
  34.         Listeners   
  35.     =========================================================================-->   
  36.   
  37.     <listener>   
  38.         <listener-class>   
  39.             org.springframework.web.util.Log4jConfigListener   
  40.         </listener-class>   
  41.     </listener>   
  42.     <listener>   
  43.         <listener-class>   
  44.             org.springframework.web.context.ContextLoaderListener   
  45.         </listener-class>   
  46.     </listener>   
  47.       
  48.   <!--========================================================================   
  49.         Servlets   
  50.     =========================================================================-->   
  51.     <servlet>   
  52.         <servlet-name>dispatcherServlet</servlet-name>   
  53.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>   
  54.         <load-on-startup>0</load-on-startup>   
  55.     </servlet>   
  56.   
  57.     <servlet-mapping>   
  58.         <servlet-name>dispatcherServlet</servlet-name>   
  59.         <url-pattern>*.do</url-pattern>   
  60.     </servlet-mapping>   
  61. <!--========================================================================   
  62.         DWR 配置   
  63.     =========================================================================-->   
  64.     <!--配置DWR拦截器-->      
  65.      <servlet>      
  66.           <servlet-name>dwr-invoker</servlet-name>      
  67.           <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>      
  68.           <init-param>      
  69.            <param-name>debug</param-name>      
  70.            <param-value>true</param-value>      
  71.           </init-param>   
  72.           <init-param>   
  73.             <param-name>classes</param-name>   
  74.             <param-value>java.lang.Object</param-value>   
  75.           </init-param>   
  76.           <load-on-startup>100</load-on-startup>   
  77.      </servlet>      
  78.      <servlet-mapping>      
  79.       <servlet-name>dwr-invoker</servlet-name>      
  80.       <url-pattern>/dwr/*</url-pattern>      
  81.      </servlet-mapping>   
  82.  <!--========================================================================   
  83.         Session   
  84.     =========================================================================-->   
  85.   
  86.     <session-config>   
  87.         <session-timeout>30</session-timeout>   
  88.     </session-config>   
  89.   
  90.         
  91.     
  92.     
  93. </web-app>  

二是:bean生成的配置。model-config.xml
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"    
  3.  "http://www./dtd/spring-beans.dtd">    
  4.  <beans>   
  5.         
  6.      <bean id="propertyConfigurer"  
  7.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
  8.         <property name="locations">   
  9.             <list>   
  10.                 <value>/WEB-INF/jdbc.properties</value>                   
  11.             </list>   
  12.         </property>   
  13.     </bean>   
  14.         
  15.    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
  16.         <property name="driverClassName" value="${jdbc.driver}" />   
  17.         <property name="url" value="${jdbc.url}" />   
  18.         <property name="username" value="${jdbc.username}" />   
  19.         <property name="password" value="${jdbc.password}" />   
  20.     </bean>       
  21.   
  22.   
  23.     <bean id="sessionFactory"  
  24.                  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"  destroy-method="close">   
  25.             <property name="dataSource">   
  26.                  <ref local="myDataSource" />   
  27.             </property>   
  28.             <property name="mappingResources">   
  29.                 <list>   
  30.                    <value> com/ssgly/model/Region.hbm.xml</value>                   
  31.                 </list>   
  32.             </property>   
  33.             <property name="hibernateProperties">   
  34.               <props>   
  35.                 <prop key="connection.characterEncoding">utf-8</prop>   
  36.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>   
  37.                 <prop key="hibernate.jdbc.batch_size">50</prop>    
  38.                 <prop key="hibernate.show_sql">true</prop>   
  39.                 <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>   
  40.                 </props>   
  41.             </property>   
  42.         </bean>   
  43.      
  44.     <bean id="transactionManager"    
  45.           class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
  46.         <property name="sessionFactory">    
  47.             <ref bean="sessionFactory"/>    
  48.         </property>    
  49.     </bean>   
  50.        
  51.     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">   
  52.          <property name="sessionFactory"> <ref bean="sessionFactory"/> </property>   
  53.     </bean>   
  54.        
  55.     
  56.      <bean id="regionDao"  class="com.ssgly.dao.RegionDAOImpl">   
  57.         <property name="hibernateTemplate">    
  58.             <ref bean="hibernateTemplate"/>   
  59.         </property>               
  60.      </bean>                                      
  61.    <bean id="businessService" class="com.ssgly.business.impl.BusinessServiceImpl">   
  62.        <property name="regionDAO"><ref  bean="regionDao" /></property>   
  63.           
  64.    </bean>   
  65.       
  66.    <bean id="todoSsglyService"  class="com.ssgly.ext.ToDoImpl">   
  67.         <property name="businessServiceImpl">    
  68.             <ref bean="businessService"/>   
  69.         </property>               
  70.    </bean>   
  71.       
  72.       
  73. </beans>  

三是:servlet配置 dispatcherServlet-servlet.xml
Java代码 复制代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"    
  3.  "http://www./dtd/spring-beans.dtd">    
  4.   
  5. <beans>   
  6.     <!--============================================================================   
  7.         URL Mapping configuration   
  8.     =============================================================================-->   
  9.   
  10.     <bean id="beanNameUrlMapping"  
  11.         class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">   
  12.         <property name="alwaysUseFullPath" value="true" />   
  13.     </bean>   
  14.    <!--============================================================================   
  15.         Velocity configuration   
  16.     =============================================================================-->   
  17.   
  18.     <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">   
  19.         <property name="contentType"><value>text/html;charset=GBK</value></property>   
  20.     </bean>   
  21.   
  22.     <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">   
  23.         <property name="configLocation" value="/WEB-INF/velocity.properties" />   
  24.         <property name="resourceLoaderPath" value="/" />   
  25.     </bean>   
  26.     
  27.     <bean id="treeRegionServlet"  name="/treeRegionServlet.do" class="com.ssgly.web.TreeRegionServlet">   
  28.         <property name="businessService">   
  29.             <ref bean="businessService"/>   
  30.         </property>   
  31.     </bean>   
  32. </beans>  

    有了这些xml的配置。Spring能将三层很好地组合起来。以上是java部分。还没有讲到extJs。extJs可以接受asp、php、java等服务器端生成的json格式的对象。就java来说 ,extJs能接受三种方式的json对象,一是servlet中拼接json对象;其次是引用json lib 包;三是DWR方式,绕过Controller(就Spring来说)或servlet,在javascript中 直接调用java业务逻辑层中的方法(通过DWR引擎),利用dwr代理或者javascript 回调函数返回json对象并在页面展示。
    本人采用了第三种DWR方式实现ExtJs生成树。要使用dwr 就的要在以上几个配置文件中配置DWR(已配)。具体的下次再说吧。
    今天就写到这里吧。不知写的怎么样?有朋友关注这一块?若支持,请鼓励一下;写的不好、不对或不懂的地方,请拍砖。(续)

    抱歉啊,这几天忙着考驾照,把这事给耽搁啊。书接上回吧。
【四】基于Spring方式的DWR配置说明。
一、首先在WEB.xml中配置dwr拦截器 代码如下(节选):
Java代码 复制代码
  1. <!--配置DWR拦截器-->      
  2.      <servlet>      
  3.              <servlet-name>dwr-invoker</servlet-name>      
  4.       <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>      
  5.           <init-param>      
  6.            <param-name>debug</param-name>      
  7.            <param-value>false</param-value>      
  8.           </init-param>   
  9.           <init-param>   
  10.             <param-name>classes</param-name>   
  11.             <param-value>java.lang.Object</param-value>   
  12.           </init-param>   
  13.           <load-on-startup>100</load-on-startup>   
  14.      </servlet>      
  15.      <servlet-mapping>      
  16.       <servlet-name>dwr-invoker</servlet-name>      
  17.       <url-pattern>/dwr/*</url-pattern>      
  18.      </servlet-mapping>  

二、dwr.xml的配置。这里将Spring管理的bean映射成javascipt操作的对象。更直观的说法就是使得页面中javascript能直接使用java中对象的方法。代码如下:
Java代码 复制代码
  1.  <?xml version="1.0" encoding="utf-8"?>   
  2. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"  
  3.     "http:///dwr/dwr20.dtd">   
  4.   
  5. <dwr>   
  6.     <allow>   
  7.         <convert converter="bean"  match="com.ssgly.model.*"/>   
  8.         <convert converter="map" match="org.directwebremoting.convert.MapConverter"/>    
  9.         <create creator="spring" javascript="treeBusinessService">   
  10.           <param name="beanName" value="businessService"/>   
  11.           <include method="getAllChildren" />   
  12.         </create>   
  13.     </allow>   
  14.      
  15. </dwr>  


    从上面的代码可以看出,javascript使用treeBusinessService.getAllChildren 方法就能够直接取出 Spring维持的业务逻辑层定义的bean----- businessService。从而完成了DWR的功能。这里当然存在安全问题,在这里暂时没有讨论,关于如何在DWR中进行安全控制,大家可以参考有关文档。本文暂不考虑。
【五】ext和服务器端交互的机制和具体实现
    一般说来,按照上面DWR的配置,就已经实现了在页面中使用java的方法。但java方法执行后生成的List 传回到页面还需要靠回调函数实现。例如下面代码就是包含了回调函数的测试页。
Java代码 复制代码
  1. <html>   
  2. <head>         
  3.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">      
  4. <title>ExtJS-树示例</title>   
  5. <link rel="stylesheet" type="text/css" href="ext2/resources/css/ext-all.css" />   
  6. <script type="text/javascript" src="ext2/adapter/ext/ext-base.js"></script>   
  7. <script type="text/javascript" src="ext2/ext-all.js"></script>   
  8.     
  9. <PRE class=java name="code"><script type="text/javascript" src="dwr/interface/treeBusinessService.js "></script>   
  10. <script type="text/javascript" src="dwr/engine.js "></script>   
  11. <script type="text/javascript" src="dwr/util.js "></script></PRE>    
  12. <BR><script type="text/javascript">   
  13. <BR>           
  14. <BR>    treeBusinessService.getAllChildren(1,function(ret){   
  15. <BR>                                     alert("一共有"+ret.length+"个子节点");   
  16. <BR>                                   });   
  17. <BR>   
  18. <BR></script>   
  19. <BR></head>   
  20. <BR>       
  21. <BR><body>   
  22. <BR><div id="tree-div"></div>        
  23. <BR></body>   
  24. <BR></html>   
  25. <BR>  


现在分析一下上面页面主要代码:

Java代码 复制代码
  1. <script type="text/javascript" src="dwr/interface/treeBusinessService.js "></script>   
  2.    

这句中的treeBusinessService就是DWR.xml中定义的
Java代码 复制代码
  1. <create creator="spring" javascript="treeBusinessService">  


下面两句是使用DWR所必需的,原样加上即可。
Java代码 复制代码
  1. <script type="text/javascript" src="dwr/engine.js "></script>   
  2. <script type="text/javascript" src="dwr/util.js "></script>  

有了上面的这些DWR配置,就能够以DWR的方式使用java的方法啦:
Java代码 复制代码
  1. <script type="text/javascript">   
  2.            
  3.     treeBusinessService.getAllChildren(1,function(ret){   
  4.                                      alert("一共有"+ret.length+"个子节点");   
  5.                                    });   
  6.   
  7. </script>  

   function(ret)就是回调函数。因为treeBusinessService.getAllChildren执行的结果是List类型,DWR解析List到页面应该是javascript的对象数组,所以ret应该是个数组,ret.length是这个数组的长度。

   上面的例子只不过是原理性的介绍,帮助我们理解javascript如何和后台进行的交互。真正要实现DWRTree 还需要专门的DWRTreeLoader代理。下面这段代码很是重要,参考了ext官方bbs上的代码,并做了修改。先提供如下:
Java代码 复制代码
  1. Ext.tree.DWRTreeLoader = function(config) {   
  2.   Ext.tree.DWRTreeLoader.superclass.constructor.call(this, config);   
  3. };   
  4.   
  5. Ext.extend(Ext.tree.DWRTreeLoader, Ext.tree.TreeLoader, {   
  6.    args:[],   
  7.    requestData : function(node, callback) {   
  8.     if (this.fireEvent("beforeload"this, node, callback) !== false) {   
  9.   
  10.         
  11.       var callParams = new Array();   
  12.       var success = this.handleResponse.createDelegate(this, [node, callback], 1);   
  13.       var error = this.handleFailure.createDelegate(this, [node, callback], 1);   
  14.       callParams.push(node.id);   
  15.       callParams.push({callback:success, errorHandler:error});   
  16.   
  17.       //todo: do we need to set this to something else?   
  18.       this.transId=true;   
  19.       this.dataUrl.apply(this, callParams);   
  20.     } else {   
  21.       // if the load is cancelled, make sure we notify   
  22.       // the node that we are done   
  23.       if (typeof callback == "function") {   
  24.         //alert(callback);   
  25.         callback();   
  26.       }   
  27.     }   
  28.   },   
  29.     processResponse : function(response, node, callback){   
  30.         try {   
  31.           for(var i = 0; i < response.length; i++){   
  32.                 var n = this.createNode(response[i]);   
  33.                 if(n){   
  34.                     node.appendChild(n);   
  35.                 }   
  36.             }   
  37.             if(typeof callback == "function"){   
  38.                 callback(this, node);   
  39.             }   
  40.         }catch(e){   
  41.             this.handleFailure(response);   
  42.         }   
  43.     },   
  44.   
  45.     handleResponse : function(response, node, callback){   
  46.         this.transId = false;   
  47.         this.processResponse(response, node, callback);   
  48.         this.fireEvent("load"this, node, response);   
  49.     },   
  50.   
  51.     handleFailure : function(response, node, callback){   
  52.         this.transId = false;   
  53.         this.fireEvent("loadexception"this, node, response);   
  54.         if(typeof callback == "function"){   
  55.             callback(this, node);   
  56.         }   
  57.     }   
  58.   
  59. });    


上面的代码可以直接在项目中使用,无需修改。
【六】最终DWRTree的实现包括 tree.js和 tree.html
tree.js完整代码如下:
Java代码 复制代码
  1.  Ext.onReady(function(){    
  2.      
  3. Ext.tree.DWRTreeLoader = function(config) {   
  4.   Ext.tree.DWRTreeLoader.superclass.constructor.call(this, config);   
  5. };   
  6.   
  7. Ext.extend(Ext.tree.DWRTreeLoader, Ext.tree.TreeLoader, {   
  8.    args:[],   
  9.    requestData : function(node, callback) {   
  10.     if (this.fireEvent("beforeload"this, node, callback) !== false) {   
  11.   
  12.         
  13.       var callParams = new Array();   
  14.       var success = this.handleResponse.createDelegate(this, [node, callback], 1);   
  15.       var error = this.handleFailure.createDelegate(this, [node, callback], 1);   
  16.       callParams.push(node.id);   
  17.       callParams.push({callback:success, errorHandler:error});   
  18.   
  19.       //todo: do we need to set this to something else?   
  20.       this.transId=true;   
  21.       this.dataUrl.apply(this, callParams);   
  22.     } else {   
  23.       // if the load is cancelled, make sure we notify   
  24.       // the node that we are done   
  25.       if (typeof callback == "function") {   
  26.         //alert(callback);   
  27.         callback();   
  28.       }   
  29.     }   
  30.   },   
  31.     processResponse : function(response, node, callback){   
  32.         try {   
  33.           for(var i = 0; i < response.length; i++){   
  34.                 var n = this.createNode(response[i]);   
  35.                 if(n){   
  36.                     node.appendChild(n);   
  37.                 }   
  38.             }   
  39.             if(typeof callback == "function"){   
  40.                 callback(this, node);   
  41.             }   
  42.         }catch(e){   
  43.             this.handleFailure(response);   
  44.         }   
  45.     },   
  46.   
  47.     handleResponse : function(response, node, callback){   
  48.         this.transId = false;   
  49.         this.processResponse(response, node, callback);   
  50.         this.fireEvent("load"this, node, response);   
  51.     },   
  52.   
  53.     handleFailure : function(response, node, callback){   
  54.         this.transId = false;   
  55.         this.fireEvent("loadexception"this, node, response);   
  56.         if(typeof callback == "function"){   
  57.             callback(this, node);   
  58.         }   
  59.     }   
  60.   
  61. });     
  62.   
  63.   
  64. var myTree = new Ext.tree.TreePanel({      
  65.         el:Ext.getBody(),     
  66.         autoScroll:true,   
  67.         animate:true,   
  68.         width:'300px',   
  69.         height:'800px',   
  70.         enableDD:true,   
  71.         containerScroll: true,    
  72.         root:new Ext.tree.AsyncTreeNode({   
  73.              text: '单位',   
  74.              draggable:false,   
  75.              id:'1' }),   
  76.         loader:new Ext.tree.DWRTreeLoader({    
  77.                    dataUrl:treeBusinessService.getAllChildren,    
  78.                    listeners : {   
  79.                               'beforeload' : function( node) {   
  80.                                    myTree.getLoader().args[0]=(node.id!='root'?node.id:"1");   
  81.                                 }   
  82.                    }   
  83.                })   
  84.     });   
  85.        
  86.     myTree.render();   
  87.   
  88.   
  89.        
  90. });  

提个醒:这句
Java代码 复制代码
  1. myTree.getLoader().args[0]=(node.id!='root'?node.id:"1");  
不能错哦,它是和 DWRTreeLoader耦合的。

tree.html是这样的:
Java代码 复制代码
  1. <html>   
  2. <head>         
  3.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">      
  4. <title>ExtJS-树示例</title>   
  5. <link rel="stylesheet" type="text/css" href="ext2/resources/css/ext-all.css" />   
  6. <script type="text/javascript" src="ext2/adapter/ext/ext-base.js"></script>   
  7. <script type="text/javascript" src="ext2/ext-all.js"></script>   
  8.     
  9. <script type="text/javascript" src="dwr/interface/treeBusinessService.js "></script>   
  10. <script type="text/javascript" src="dwr/engine.js "></script>   
  11. <script type="text/javascript" src="dwr/util.js "></script>   
  12. <script type="text/javascript" src="js/tree.js"></script>    
  13.      
  14. </head>   
  15.        
  16. <body>   
  17.     
  18. </body>   
  19. </html>  


  好了,基于Spring+hibernate+dwr+EXTJs的DWRTreeLoader的实现就是这样。本想提供完整代码下载。但想来想去还是让读者自己结合我的文章边做边体会比较好。说不定还能优化我的代码呢。你说是吗?

  还有comBoboxTree的实现没有写。也不知大家感兴趣没?还是欢迎大家多提意见吧。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多