(更新版)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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi