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

相关文章

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

Python实现一键PDF转Word(附完整代码及详细步骤)

《Python实现一键PDF转Word(附完整代码及详细步骤)》pdf2docx是一个基于Python的第三方库,专门用于将PDF文件转换为可编辑的Word文档,下面我们就来看看如何通过pdf2doc... 目录引言:为什么需要PDF转Word一、pdf2docx介绍1. pdf2docx 是什么2. by

使用Python实现网页表格转换为markdown

《使用Python实现网页表格转换为markdown》在日常工作中,我们经常需要从网页上复制表格数据,并将其转换成Markdown格式,本文将使用Python编写一个网页表格转Markdown工具,需... 在日常工作中,我们经常需要从网页上复制表格数据,并将其转换成Markdown格式,以便在文档、邮件或

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、

Python实现pdf电子发票信息提取到excel表格

《Python实现pdf电子发票信息提取到excel表格》这篇文章主要为大家详细介绍了如何使用Python实现pdf电子发票信息提取并保存到excel表格,文中的示例代码讲解详细,感兴趣的小伙伴可以跟... 目录应用场景详细代码步骤总结优化应用场景电子发票信息提取系统主要应用于以下场景:企业财务部门:需

基于Python实现智能天气提醒助手

《基于Python实现智能天气提醒助手》这篇文章主要来和大家分享一个实用的Python天气提醒助手开发方案,这个工具可以方便地集成到青龙面板或其他调度框架中使用,有需要的小伙伴可以参考一下... 目录项目概述核心功能技术实现1. 天气API集成2. AI建议生成3. 消息推送环境配置使用方法完整代码项目特点

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请