jquery树形表格treetable插件怎么用

JavaScript030

jquery树形表格treetable插件怎么用,第1张

jquery树形表格treetable插件使用方法步骤:

第一步:

1.上官网下载。

2.插件引用,当下载的时候,会有很多个文件,但是根据api来看,如果只想做简单的效果,js除了引用juquery外,只需要引用jquery.treetable.js插件,如果想让它有默认的外观样式还需要引入它们的jquery.treetable.css和jquery.treetable.theme.default.css

第二步:建立table格式

<table id="example-advanced">

<tr data-tt-id="1">

<td>大家电</td>

</tr>

<tr data-tt-id="2" data-tt-parent-id="1">

<td>---电视</td>

</tr>

<tr data-tt-id="3" data-tt-parent-id="1">

<td>---洗衣机</td>

</tr>

<tr data-tt-id="4" data-tt-parent-id="1">

<td>---冰箱</td>

</tr>

</table>

第三步:引入JS

/* 初始化数据 */

$("#example-advanced").treetable({ expandable: true })/* 高亮显示 */$("#example-advanced tbody").on("mousedown", "tr", function() {

$(".selected").not(this).removeClass("selected")

$(this).toggleClass("selected")

})/* 点击展开&&关闭 */<a href="#" class="btn btn-blue" onclick="jQuery('#example-advanced').treetable('expandAll')return false">展开</a>

<a href="#" class="btn btn-blue" onclick="jQuery('#example-advanced').treetable('collapseAll')return false">关闭l</a>

一、JQuery树形控件

Jquery树形控件是一款基于JQuery+bootstrap、完全通过js和样式手写出来的非常轻量级的控件,网上很多地方都能看到它的影子。它功能简单、用户体验不错。对于一些简单的层级关系展示比较实用,但对于节点的增删改实现起来就不容易了,如果非要做,可能需要自己去封装。

1、一睹初容

全部收起

展开一级

全部展开

2、代码示例

此控件实现起来也非常简单,只需要引用jQuery和bootstrap组件即可。

<link href="~/Content/Tree1/css/bootstrap.min.css" rel="stylesheet" />

<link href="~/Content/Tree1/css/style.css" rel="stylesheet" />

<script src="~/Scripts/jquery-1.10.2.js"></script>

<script type="text/javascript">

$(function(){

$('.tree li:has(ul)').addClass('parent_li').find(' >span').attr('title', 'Collapse this branch')

$('.tree li.parent_li >span').on('click', function (e) {

var children = $(this).parent('li.parent_li').find(' >ul >li')

if (children.is(":visible")) {

children.hide('fast')

$(this).attr('title', 'Expand this branch').find(' >i').addClass('icon-plus-sign').removeClass('icon-minus-sign')

} else {

children.show('fast')

$(this).attr('title', 'Collapse this branch').find(' >i').addClass('icon-minus-sign').removeClass('icon-plus-sign')

}

e.stopPropagation()

})

})

</script>

<div class="tree well">

<ul>

<li>

<span><i class="icon-folder-open"></i>顶级节点1</span><a href="">Goes somewhere</a>

<ul>

<li>

<span><i class="icon-minus-sign"></i>一级节点1</span><a href=""></a>

<ul>

<li>

<span><i class="icon-leaf"></i>二级节点1_1</span><a href=""></a>

</li>

</ul>

</li>

<li>

<span><i class="icon-minus-sign"></i>一级节点2</span><a href=""></a>

<ul>

<li>

<span><i class="icon-leaf"></i>二级节点2_1</span><a href=""></a>

</li>

<li>

<span><i class="icon-minus-sign"></i>二级节点2_2</span><a href=""></a>

<ul>

<li>

<span><i class="icon-minus-sign"></i>三级节点2_1</span><a href=""></a>

<ul>

<li>

<span><i class="icon-leaf"></i>四级节点2_1</span><a href=""></a>

</li>

<li>

<span><i class="icon-leaf"></i>四级节点2_2</span><a href=""></a>

</li>

</ul>

</li>

<li>

<span><i class="icon-leaf"></i>三级节点2_2</span><a href=""></a>

</li>

<li>

<span><i class="icon-leaf"></i>三级节点2_3</span><a href=""></a>

</li>

</ul>

</li>

<li>

<span><i class="icon-leaf"></i>二级节点2_3</span><a href=""></a>

</li>

</ul>

</li>

</ul>

</li>

<li>

<span><i class="icon-folder-open"></i>顶级节点2</span><a href=""></a>

<ul>

<li>

<span><i class="icon-leaf"></i>一级节点2_1</span><a href=""></a>

</li>

</ul>

</li>

</ul>

</div>

这些代码都是直接从网上down下来的,节点上面的图标可以通过样式修改,图标样式也是基于bootstrap的。如果需要动态添加节点,可以自己封装组件去拼html,实现起来应该也比较简单。由以上可知此组件的轻量级,如果你需要对节点作增删改或者选择等操作,不要急,下面的控件可能比较适用。

二、文件树编辑插件Treed

这个组件是从网上找到的,最初演示,组内成员一致觉得效果很赞。因为它通过树形展示,方便的提供了节点的增删改。节点的伸缩效果也比较好。好了来看看。

之所以会造成卡顿,是因为该组件是一次性将所有数据全部渲染,dom数量过于庞大,并且在展开树操作的时候,用了大量递归循环语句,性能受到严重影响,造成卡顿。

我想到的解决方式有两种:

一:分页,让后端添加分页查询,以节点数统计数据条数进行展示。(但实际需求中较少,一般树形表格都是不分页)。

二:将请求到的树形数组数据备份(tableDataCopy),初始化仅仅展示指定层级(如第一层树)的数据,将第一层下面的所有的children全部置为null,并记录存在children的节点,设置hasChild的状态,判断是否存在子节点。这样就不会在初始化页面时展示完所有数据,实现按需加载。

        以上仅仅能满足展示功能,当存在操作节点上移下移/删除/编辑等操作的情况下,展示的节点就不能同步刷新(因为备份数据不能双向数据绑定了)。处理办法:更新节点(两种方式,第一种使用render()来实现,第二种是给表格绑定key(利用diff算法),只要操作了数据,就改变key就能实现节点更新)。

请求数据和展开代码如下:

// 获取树形列表

getList(active) {

this.loading = true

let data = Object.assign({}, this.searchForm)

API.getDepartmentListAll(data)

.then((res) =>{

// this.tableData = res.data

this.expandRow.push(res.data[0].id)//默认展开

this.tableDataCopy = res.data || [] // 备份的全量数据

if (active) { //是否是操作按钮点击的数据

this.tableData = this.commonJs.mapNewTableData(res.data,this.expandRow)//展开已展开的数据

} else {

this.tableData = this.commonJs.mapNewTableData(res.data,res.data[0].id)//默认展开第一层

}

this.componentKey += 1//销毁更新dom

}).finally(() =>{

this.loading = false

this.getTableHeight()

})

},

// 展开按钮

getChildrens(tree, treeNode, resolve) {

let data = Object.assign({}, this.searchForm, {

deptId: tree.id

})

API.getDepartmentListAll(data) //传入展开按钮层级节点的id,获取子节点

.then((res) =>{

this.tableDatas = JSON.parse(JSON.stringify(res.data.children)).map(item =>{ // 展示数据

// hasChildren 表示需要展示一个箭头图标

item.hasChildren = item.children &&item.children.length >0

// 只展示一层也可以配置tree-props里面的children为其他字段

item.children = null

// 记住层级关系

item.idList = [item.id]

return item

})

resolve(this.tableDatas)

})

},

登录后复制

当存在操作按钮,数据更新后,利用上述key更新节点后 ,会将展开的状态初始为初次进度页面的状态,不能停留在操作的节点。解决方法:可以在点击操作按钮的时候,使用findParentNode方法递归查询到该节点所有的祖先节点id并记录(expandRow,该变量也是树形表格:expand-row-keys默认展开的数据),然后再请求刷新数据时,通过mapNewTableData()方法递归处理将对应的祖先节点id对应的children给展示处理,其他的节点还是一样的置为null。代码如下:

/**

*

* @param 递归,当前节点的祖先节点id数组(包含自身)

* acceptUnitNodes树状结构数据,ids当前节点的id

*/

findParentNode(acceptUnitNodes, ids) {

var parentNodes = [] // 所有父节点

var forfun = function(id, nodes) {

for (var i = 0i <nodes.lengthi++) {

var currentNode = nodes[i]

if (currentNode.id === id) {

return currentNode.id

} else if (currentNode.children) {

var validNodeId = forfun(id, currentNode.children)

if (validNodeId &&parentNodes.indexOf(validNodeId) <0) {

parentNodes.push(validNodeId)

}

if (validNodeId) {

return currentNode.id

}

}

}

}

var validNodeId = forfun(ids, acceptUnitNodes)

if (validNodeId &&parentNodes.indexOf(validNodeId) <0) {

parentNodes.push(validNodeId)

}

return parentNodes

},

//递归处理数据,当有展开记录的时候,将有展开记录的数据的子节点显示出来

mapNewTableData(data, pidArr) {

let dataNew = JSON.parse(JSON.stringify(data))

function mapNewArr(dataNew, pidArr) {

dataNew.map(item =>{

if (pidArr.indexOf(item.id) === -1) {

item.idList = [item.id]

item.hasChildren = true

item.children = null

// 记住层级关系

return item

} else {

mapNewArr(item.children, pidArr)

}

})

return dataNew

}

mapNewArr(dataNew, pidArr)

return mapNewArr(dataNew, pidArr)

},

登录后复制

操作按钮:

//上移//下移

upDownLayer(index, row, type) {

this.expandRow = (this.commonJs.findParentNode(this.tableDataCopy, row.id)).splice(1)//调工具,获取点击当前节点的祖先节点id数组。

let loading = Loading.service({

target: document.querySelector(".tableBox"),

})