码迷,mamicode.com
首页 > 其他好文 > 详细

jonmiles/bootstrap-treeview踩坑记录(吐槽下checkNode和expandNode方法使用)

时间:2020-06-01 12:00:00      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:项目   mamicode   通过   使用   check   typeof   incr   each   字段   

现在在2020年了,jonmiles/bootstrap-treeview 项目已经归档了,并且最后一次更新在2015年。但是,项目中使用到了这个库,所以,没得选择,只能粪不顾身跳入坑里。

这篇文章主要吐槽bootstrap-treeview的两个方法:checkNodeexpandNode 的使用。

checkNode 方法

顾名思义,这个方法用来勾选 node 节点。根据文档说明:

技术图片

checkNode 方法的第一个参数可以是 node 对象或者 nodeId 数字。这里要特别注意 nodeId 数字,并不是想当然的初始化 treeview 所传入的 data 属性中对象的 id 字段。原先我也先入为主的以为是 data 对象中的 id 字段,但是发现不是,于是阅读了源代码。

	/*
		Identifies a node from either a node id or object
	*/
	Tree.prototype.identifyNode = function (identifier) {
		return ((typeof identifier) === ‘number‘) ?
						this.nodes[identifier] :
						identifier;
	};

identifyNode 方法,用来通过 identifier 标识来返回 node 对象。如果 identifier 是数字,就返回 this.nodes[identifier],否则原样返回。

由于要找的是 identifier 是数字时所代表的含义,找到 setInitialStates 方法,它用来初始化所有节点及节点的状态:

	Tree.prototype.setInitialStates = function (node, level) {

		if (!node.nodes) return;
		level += 1;

		var parent = node;
		var _this = this;
		$.each(node.nodes, function checkStates(index, node) {

			// nodeId : unique, incremental identifier
			node.nodeId = _this.nodes.length;

	// 中间代码省略...

			// index nodes in a flattened structure for use later
			_this.nodes.push(node);

			// recurse child nodes and transverse the tree
			if (node.nodes) {
				_this.setInitialStates(node, level);
			}
		});
	};

从这两行关键代码可以看出来 nodeId 是从 0 开始的自增的整数,而并非 data 对象中的 id 字段:

			// nodeId : unique, incremental identifier
			node.nodeId = _this.nodes.length;

	// 中间代码省略...

			// index nodes in a flattened structure for use later
			_this.nodes.push(node)

啰嗦一大堆,结论就是 nodeId 是 treeview 自动生成的从 0 开始的自增整数。那解决想通过 data 对象中的 id 字段来实现 checkNode 该怎么做呢?

分为两步,要在 bootstrap-treeview 新增一行代码,并且使用这一行新增的代码:

#1

bootstra-treeview.js 的源码里的 var Tree = function () { ... } 最后 return 返回的对象中新增一行代码:

			findNodes: $.proxy(this.findNodes, this)

#2

完成 1 步骤后,我们就可以在源码外调用 findNodes 方法。这个方法很强大,可以通过正则表达式查找 nodes 节点中的指定属性的内容,并返回所有匹配的节点,findNodes 的源码:

技术图片

使用 findNodes 方法,就能够根据 id 属性查找所需的节点,然后传入 checkNodes 方法里:

var node = $(‘#target‘).treeview(‘findNodes‘, [‘^‘ + n + ‘$‘, ‘g‘, ‘id‘]);
if (!node || !node.length) {
    return;
}
$(‘#target‘).treeview(‘checkNode‘, node);

$(‘#target‘).treeview(‘findNodes‘, [‘^‘ + n + ‘$‘, ‘g‘, ‘id‘]) 是含义是查找 nodes 节点中 id 属性值等于变量 n 的所有节点。

expandNode 方法

expandNode 方法用来展开指定的 node 节点,根据文档说明:

技术图片

expandNode 方法的第一个参数和 checkNode 方法的一样,可以接受 node 对象或者 nodeId 数字。第二个参数可选传入 levels 指定要展开节点的层级。默认就是 1 了,只展开一层;如果 levels: 2,那么会展开两层。

实际情况中,使用了 checkNode 方法勾选节点后,想要自动展开这些节点,按照 expandNode 方法的实现是完成不了这个需求的。比方说,勾选了第三层级的 C 节点,要实现自动展开这个节点,需要先展开 C 节点的父节点(位于第二层级的某节点),再展开 C 节点的父节点的父节点(位于第一层级的某节点)。

把这个需求用代码实现,方法取名为 expandRealNode(这才是我心目中的展开节点方法:-D):

#1

Tree.prototype.expandNode = function (identifiers, options) { ... } 的后面加上如下代码:

	Tree.prototype.expandRealNode = function (identifiers, options) {
		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
			var real = node;
			while (true) {
				real = this.getParent(real);
				console.log(real);
				if (!real || !real.hasOwnProperty(‘nodeId‘)) {
					break;
				}
				this.setExpandedState(real, true, options);
			}
		}, this));

		this.render();
	};

#2

bootstra-treeview.js 的源码里的 var Tree = function () { ... } 最后 return 返回的对象中新增一行代码:

expandRealNode: $.proxy(this.expandRealNode, this)

expandRealNode 的使用方法示例:

var node = $(‘#target‘).treeview(‘findNodes‘, [‘^‘ + n + ‘$‘, ‘g‘, ‘id‘]);
if (!node || !node.length) {
    return;
}
$(‘#target‘).treeview(‘checkNode‘, node);

$(‘#target‘).treeview(‘expandRealNode‘, node);

总结

主要分析了 bootstrap-treeview 源码里的 checkNodeexpandNode 方法的具体的含义,并按需改造成适合自己使用的场景。

<全文完>

jonmiles/bootstrap-treeview踩坑记录(吐槽下checkNode和expandNode方法使用)

标签:项目   mamicode   通过   使用   check   typeof   incr   each   字段   

原文地址:https://www.cnblogs.com/imzhi/p/bootstrap-view-step-hold.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!