(更新版)ExtJS Tree利用json(直接传List TreeNode,不需要转化为JSONArray)在Struts 2实现Ajax动态加载树结点

本文主要是介绍(更新版)ExtJS Tree利用json(直接传List TreeNode,不需要转化为JSONArray)在Struts 2实现Ajax动态加载树结点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这次能改进,我得写一个人--斌哥。他也是刚开始学JavaScript,加我QQ,我们是这样认识的。parentId node 属性都是他创造的,也是动态异步加载的关键部分之一。这次的改进,我个人认为这应该是动态加载最简洁的做法。如有其它,还望高人指教,Advance in thanks!

 

定义动态树的结点类 TreeNode.java

切记 该类的属性名称大部分 要和 Ext.tree.AsyncTreeNode或者Ext.tree.Node 的 Properties和Config Options一一对应,这样会自动导入到 Node 的属性中,这功能好迷人哦!但也可以传一些自己程序中要用的变量(如state)。

每个属性的具体含义请详见ExtJS API Documentation,官方网址:http://www.extjs.com/

public class TreeNode {

    private String id;// The node id
   
    // 新增属性,这是实现动态异步加载的关键属性(09.10.31尝试后发现不用parentId也可以实现动态异步加载)
    private String parentId;// The parent node id

    
    private int state;// 自己程序中用到的参数,具体怎么访问请参见下面的 treeNav.js
   
    private String text;

//    private List<TreeNode> children = new ArrayList<TreeNode>(); // 该属性不能实现异步加载
   
    private String qtip;
    
    private String icon;
   
    private Boolean leaf;
    
    private Boolean expanded;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    其它属性的 getter 和 setter 方法省略......
}

这个类没有实现序列化,但也可以序列化。两者的内在不同有待深究。

序列化代码如下所示,其它不变:

import java.io.Serializable;
public class TreeNode implements Serializable {
    private static final long serialVersionUID = 7261712903068621559L;

 

ApplyFormAction .java

想实践 Struts 2 结合 Spring 实现项目的朋友,强烈推荐《Struts 2 In Action》(我也是第一次读英文版,很容易理解,电子书PDF网上有下载),内容很全。官方网址:http://struts.apache.org/

package cn.hdu.action.admin;

import java.util.ArrayList;
import java.util.List;

import cn.hdu.domain.admin.*;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import cn.hdu.service.admin.*;

@SuppressWarnings("serial")
public class ApplyFormAction extends ActionSupport{
    // 当单击节点并触发Action时,都会将节点的id加载到参数中,而node一方面保存id,另一方面又是父节点id,服务于" treeNode.setParentId(node);"
    private String node;

     private List<TreeNode > treeNodes;
    /**
     * 只加载下一层节点信息
     */
    public String bindAsTree()
    {
        results = applyFormService.findAll();
       
        if(results != null) {
            treeNodes = new ArrayList<AdminTreeNode>();
           
            AdminTreeNode treeNode;
            for(final ApplyForm af: results) {
                treeNode = new AdminTreeNode();
                treeNode.setId(af.getFormId().toString());
                treeNode.setParentId(node);
                treeNode.setText(af.getShortName());
                treeNode.setState(af.getState());
                treeNode.setQtip(af.getFormName());
                treeNode.setIcon("images/icoImage/tree+.gif");
                treeNode.setLeaf(false);
                treeNodes.add(treeNode);
            }

            /* 首先,我能做出这个要感谢先行者的付出才使我更向前做一步!我这个的优势:不需要经过下面的转化,更不用将 nodesString 先输出到 JSP 页面上,然后 JavaScript 在读取它。这个就减省了这些不必要的转化时间,优势有没有自己衡量吧 ^-^
            JSONArray jsonObject = JSONArray.fromObject(treeNodes);
            try {
                nodesString = jsonObject.toString();
            } catch(Exception e) {
                nodesString = "ss";
            }
            */
        }
       
        return SUCCESS;
    }

    public String getNode() {
        return node;
    }

    public void setNode(String node) {
        this.node = node;
    }

     public List<TreeNode> getTreeNodes() {
        return treeNodes;
    }

    public void setTreeNodes(List<TreeNode> treeNodes) {
        this.treeNodes = treeNodes;
    }


}

 

 

struts.xml

因为用到了 extends ="json-default" ,所以要导入 jsonplugin-0.30.jar

想了解更多关于 Struts 2 的 JSON 插件的朋友,不妨进入http://cwiki.apache.org/S2PLUGINS/json-plugin.html

<param name="root ">中的 root 设置是实现该功能成功的关键点之一。

<action name="bindAsTree" class="cn.hdu.action.admin.ApplyFormAction" method="bindAsTree">
                <result type="json">
                    <param name="root ">  <!-- 这里的name属性值一定要为 root,
Use the "root" attribute(OGNL expression) to specify the root object to be serialized. The parameter "root" should point to the getter property of the action object which contains the object to convert to JSON string data.    -->
                        treeNodes <!-- 一定要和
ApplyFormAction .java 中的红色标记 treeNodes 变量相同 -->
                    </param>
                </result>

        
</ action >
</ package >

 

 

表现层

treeNav.js

利用 ExtJS 作为开发工具的朋友,一定要充分利用其官方网站:http://www.extjs.com/。上面不但提供了各控件的不同功能实现的实例(可视化)和源代码(Firefox浏览器的Firebug调试插件可以得到所有的源码,好好利用吧),但可惜都不是动态的。还有就是非常详细的 API Documentation,这是开发人员的首选参考资料,可以在其官方网址:http://www.extjs.com/ 下载到。

Ext.onReady(function(){
    Ext.BLANK_IMAGE_URL = 'ext-2.0.2/resources/images/default/s.gif';
    Ext.QuickTips.init();
 
    // set the root
  var root = new Ext.tree.AsyncTreeNode( {
    text : '根结点',
    draggable : false,
    id : '-100'
  });

   var tree = new Ext.tree.TreePanel( {
     rootVisible: false,
//     height: 500,
     margins: '5 5 4 5',
     autoScroll: true,
//     el: 'tree',
     renderTo: 'tree ',    // Using this config, a call to render() is not required (在html中存在一个 id 为 tree 的结点)
     animate: true,
     enableDD: false,
     title: '计划体系分类',
     root: root,    // You must define the root variable before when you set the root config
     loader: new Ext.tree.TreeLoader({
       dataUrl : 'admin/bindAsTree.action'
     }),
     listeners: {
             beforeclick: function(node, e) {
                     if(node.id[0] != 'r') {
                         if(node.attributes.state == 2) { // You can use this property to access any custom attributes you supplied (你可以通过
attributes 这个 属性获得任何你提供的属性值 )
                             jumpToApplyFrame(parseInt(node.id));
                         } else if(node.attributes.state == 1) {
                             Ext.Msg.alert('友情提示','此类项目申报尚在建设中。。。请关注!',function(){});
                         } else if(node.attributes.state == 3) {
                             Ext.Msg.alert('友情提示','此类项目申报已暂停使用!',function(){});
                         }
                     }
                 },
                 click:  function(node, e) {
                     if(node.isLeaf()) {
                        
                     } else {
                         // This node is expanded when it is not leaf node
                         node.toggle();
                     }
                 }
           }
   });

//   tree.setRootNode(root);
//   tree.render('tree');
   root.expand();
});

function jumpToApplyFrame(formId)
{
    var formIdType = document.getElementById('formIdType');
    var paraForm = document.getElementById('id_treePara');
    formIdType.value = formId;
    paraForm.submit();
}

 

最后,只要在相应的 html 文件中有如下代码即可:

<div id="tree"></div>

大功告成!

 

小结:

在STRUTS中使用EXTJS中的TREE实现异步加载树节点 http://www.blogjava.net/aoneany/articles/193537.html 这篇的 struts.xml 的 params="root"最为关键,那是最容易显示不了效果的地方,参见上文的 xml 文件即可。这是个牛人啊,崇拜!

 

还有一点教训 ,希望对后来者有用:

(1) 我在设置 TreeNode 的 id 属性时,将一些结点的 id 属性设置相同。这导致只有其中一个结点可用,其它的被自动屏蔽为不可用

 

(2)关于s.gif 文件的问题
     
       该问题会在系统不连互联网的情况下暴露。
     
       因为ExtJS在生成Tree时,默认情况下,总是访问http://extjs.com/s.gif下载这个s.gif图片文件。
 
       在不连网的情况下,树节点的导航图片显示不出,通过右键属性可知,是http://extjs.com/s.gif。
 
       通过搜索,发现该s.gif是在ext-base.js这个文件中定义的:
   
       BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif"
 
       并且ExtJS中的示例程序是带有这个s.gif图片文件的。     
 
       根据具体应用情况,把ext-base.js修改成为:
 
       BLANK_IMAGE_URL:"../images/default/s.gif"
 
       或在mytree.js 文件开头加入如下语句:Ext.BLANK_IMAGE_URL="../images/default/s.gif"; 建议这么做。

 

Ext.BLANK_IMAGE_URL needs to be better for the end developer

 Ext.BLANK_IMAGE_URL=Ext.isIE6||Ext.isIE7||Ext.isAir? "resources/images/default/s.gif" : "data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";

 

2009年9月2日,本人碰到的问题。如果对 s.gif 的引用路径不正确(即不能加载该图片),会导致树的树形导航线不能显示,忘朋友们注意。
 
 
(3) 调试的时候,JS报错:未结束的字符串常量。
 
      这个问题是因为JS调用时没有指定字符集,造成JS里的汉字出现乱码引起的。
 
      调用JS时,可以指定使用字符集。
 
      如:<script type="text/javascript" defer=true src="xxx.js" charset="utf-8">

这篇关于(更新版)ExtJS Tree利用json(直接传List TreeNode,不需要转化为JSONArray)在Struts 2实现Ajax动态加载树结点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/597985

相关文章

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

Spring 请求之传递 JSON 数据的操作方法

《Spring请求之传递JSON数据的操作方法》JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串,主要负责在不同的语言中数据传递和交换,这... 目录jsON 概念JSON 语法JSON 的语法JSON 的两种结构JSON 字符串和 Java 对象互转