树形节点异步加载

一,准备树形实体。

二,组装数据,注意一定要将父级节点的state在后端返回数据时关闭,要不在界面不会出现,可选的子节点

三,前端处理

一,



import java.util.TreeSet;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;
import lombok.Setter;
import lombok.AccessLevel;

/**
 * 树实体,此树结构符合easyui 的tree结构
 * 
 *
 */
@Data
public class TreeEntity implements Comparable<TreeEntity>
{
	/**
	 * 节点收缩状态标识
	 */
	public static final String STATE_CLOSED = "closed";
	/**
	 * 节点展开状态标识
	 */
	public static final String STATE_OPEN = "open";
	
	/**
	 * 空图标的样式
	 */
	public static final String NULL_ICON="icon-blank";
	/**
	 * 文件夹图标标式
	 */
	public static final String FOLDER_ICON="tree-folder";
	/**
	 * 节点id
	 */
	private String id;
	/**
	 * 节点显示文本
	 */
	private String text;
	
	/**
	 * 节点显示的图标
	 */
	private String iconCls;
	
	/**
	 * 是否勾选
	 */
	private boolean checked;
	
	/**
	 * 节点默认状态(open、closed)
	 */
	private String state;
	
	/*
	 * 父节点标识值
	 */
	private String parentId;

	/**
	 * 排序值
	 */
	private int sort;
	/*
	 * 是否已加载(用于子节点的延时加载)
	 */
	@JsonIgnore
	private boolean isLoad;
	
	/**
	 * 节点自定义属性
	 */
	private Object attributes;
	
	/**
	 * 子节点集
	 */
	@Setter(AccessLevel.PROTECTED)
	private TreeSet<TreeEntity> children;

	public TreeEntity()
	{
		children=new TreeSet<TreeEntity>();
	}
	
	/**
	 * 构造节点
	 * @param sId
	 * @param sText
	 * @param sParentId
	 * @param iSort
	 * @param sIcon 节点图标样式定义(null表示默认图标,""表示使用空图标)
	 */
	public TreeEntity(String sId,String sText,String sParentId,int iSort,String sIcon)
	{
		this();
		id=sId;
		text=sText;
		parentId=sParentId;
		sort=iSort;
		if(sIcon!=null){
			if(sIcon.isEmpty())
				sIcon=NULL_ICON;
			iconCls=sIcon;
		}
	}

	@Override
	public int compareTo(TreeEntity o)
	{
		if(o==null) return 1;
		if(this==o) return 0;//如果是同一对象,返回0(用于移除)
  	//注意:不能返回0,因为在TreeSet排序时,如果比较是0值时,会认为是在同一个位置放置元素(将会覆盖原来的元素)
		if(this.sort==o.sort){//如果排序值相同,再比较标题
			String stext=this.text;
			if(stext==null)stext="";
			int ir=stext.compareTo(o.text);
			if(ir==0){
				stext=this.id;
				if(stext==null)stext="";
				ir=stext.compareTo(o.id);
			}
			return ir==0?1:ir;//仍相等,返回大于
		}
		return (this.sort<o.sort)?-1:1;
	}
	
}

二,

public TreeEntity buildAdministrativeTree(AdministrativeDivisionEntity info)
	{
		TreeEntity root = new TreeEntity();
		root.setId(info.getCode());
		root.setText(info.getLname());
		root.setIconCls("icon-blank");
		if(info.getCode().length()<=4){
			root.setState("closed");
		}
		List<AdministrativeDivisionEntity> list = info.getChildren();
		if(list!=null&&list.size()>0){
			for(AdministrativeDivisionEntity data : list){
				root.getChildren().add(buildAdministrativeTree(data));
			}
		}
		return root;
	}
三,

1,jsp:

<input id="deptDistrict" class="easyui-combotree" style="width: 100%;"
						   data-options="editable:true"/>

2,js:

//Ajax请求,返回的内容将根据请求头MIME 信息来判断。
//url:请求地址
//data:请求数据内容
//prop:请求参数,包含属性
//  msg,操作描述,一般在不需要自己处理返回结果的情况下,能友好提示用户的信息(不设置或空,默认为“操作”)
//  sFn,执行成功后的回调方法(参数为服务器返回结果),不设置或空,默认为显示操作成功提示
//  fFn,执行失败后的回调方法(参数1为请求对象,参数2为提示信息,参数3为异常信息),不设置或空,默认为显示操作失败提示
//  async,是否异步调用请求,默认为true(即异步调用)
//  method,请求方法,默认为POST
//  jsonObj,是否将数据以json串发送请求(会使用invokeJsonObj方法发送请求)
function invokeJson(url,data,prop){
	if(!prop) prop = {};
	if(prop.jsonObj){invokeJsonObj(url,data,prop); return;}
	if(!prop.msg)  prop.msg = '操作';
	if(!prop.sFn) {prop.sFn = function(data){showSuccess(prop.msg+'成功');}};//成功的方法
	if(!prop.fFn) {prop.fFn = function(xhr,data,ex){showError(prop.msg+'失败:'+analyseError(xhr.responseText));}}//失败的方法
	if(typeof(prop.async)=="undefined" || prop.async==null) prop.async = true;
	if(!prop.method) prop.method="POST";
	else if(prop.method.toUpperCase()=="GET"){
		url=tagGetRequest(url);
	}
	$.ajax({ 
		url: url,
		type:prop.method,
		async : prop.async,
		data:data,
		success: prop.sFn,
		error: prop.fFn
	});
}
$(function(){
	var t1=$('#deptDistrict').combotree('tree');
	loadTree(t1);
	addTreeChildren(t1);
	
	
});


function addTreeChildren(tree){
	tree.tree({
		onBeforeExpand: function (node) {
			// 展开节点搜索子节点,并添加到树结构里
			if (node.children.length > 0 || node.id == 'notDefinition') {
				return;
			}
			var id = node.id;
			invokeJson("/mainWeb/mystestChildren", { code: id }, {
				method:"GET",
				async: false,
				sFn: function (data, textStatus) {
					tree.tree('append', {
						parent: node.target,
						data: data
					});
					$(node.target).next().css("display", "block");
				}, fFn: function (data) {
					layer.msg("查询失败");
				}
			});
		}
	});
}


function loadTree(t){
	var url='/mainWeb/mytest';
	invokeJson(url, null, {
		method:"GET",
		sFn: function (data) {
			t.tree({
				data: data,
				onLoadSuccess: function () { //默认折叠所有节点
					t.tree("collapseAll");
				}
			});
		}
	});
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Vue 中实现树形组件异步加载,可以使用递归组件和异步加载数据的方式实现。一般来说,树形组件的数据都是嵌套的,每个节点有自己的子节点。当节点很多的时候,需要采取异步加载的方式,将一部分节点延迟加载。下面是具体实现步骤: 1. 创建树形组件:首先需要创建一个树形组件,该组件中包含了递归组件的方式,即组件中会嵌套自身。 2. 设置异步加载方法:在树形组件中设置一个异步加载方法,该方法接收节点的 ID 作为参数,然后根据节点 ID 加载节点数据。 3. 设置递归组件:在树形组件中设置一个递归组件,用于逐层展示树形节点。在递归组件中,需要设置一个条件,用于判断当前节点是否需要延迟加载节点。如果需要延迟加载,则在节点展开时调用异步加载方法加载节点数据。 4. 渲染树形组件:最后,在父组件中渲染树形组件,并传入顶层节点的数据。 下面是示例代码: ``` <template> <div> <ul> <tree-node v-for="node in nodes" :key="node.id" :node="node"></tree-node> </ul> </div> </template> <script> import TreeNode from './TreeNode.vue' export default { components: { TreeNode }, data () { return { nodes: [] } }, mounted () { this.loadRootNodes() }, methods: { loadRootNodes () { // 加载顶层节点数据 // ... this.nodes = rootNodeData } } } </script> ``` ``` <template> <li> <div @click="toggle"> {{ node.label }} </div> <ul v-if="!isLeaf && expanded"> <tree-node v-for="childNode in childNodes" :key="childNode.id" :node="childNode"></tree-node> </ul> </li> </template> <script> export default { props: { node: { type: Object, required: true } }, data () { return { childNodes: null, expanded: false } }, computed: { isLeaf () { return !this.node.hasChild } }, methods: { toggle () { if (this.isLeaf) { return } if (!this.childNodes) { this.loadChildNodes() } this.expanded = !this.expanded }, async loadChildNodes () { // 加载节点数据 // ... this.childNodes = childNodeData } } } </script> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值