全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

JS 组件系列之 bootstrap treegrid 组件封装过程

正文

前言:最近产品需要设计一套相对完整的组织架构的解决方案,由于组织架构涉及到层级关系,在表格里面展示层级关系,自然就要用到所谓的treegrid。可惜的是,一些轻量级的表格组件本身并没有自带树形表格的功能,比如bootstrapTable就没有这个功能,怎么办呢?如果是jqgrid、easyUI的表格,treegrid的效果可以说是轻而易举就能解决,而项目目前用的就是bootstrapTable,不可能这个时候因为这个需求去换组件吧。博主分析了下,无非就两种解决方案:一种就是扩展bootstrapTable的treegrid功能;第二种就是再找一个单独的treegrid组件去实现这个功能。在网上找了下,找到了一个效果还不错的treegrid第三方组件,于是做了下封装,今天分享出来,供大家参考。

一、开源的treegrid

1、组件效果预览

最原始的效果

bootstrap样式的效果

这个是组件最原始的效果,后面会告诉大家博主做了哪些封装以及加了哪些功能。

在此还是给出一个封装过的效果吧!

2、组件开源地址

最后还是给出github上面一个开源的treegrid组件。

github开源地址:https://github.com/maxazan/jquery-treegrid

文档示例地址:http://maxazan.github.io/jquery-treegrid/

bootstrap样式的demo以及使用:http://maxazan.github.io/jquery-treegrid/examples/example-bootstrap-3.html

二、封装treegrid

1、组件封装的必要性

(1)纵观组件的所有的demo和文档,基本都是说的我们直接写死的table标签,然后通过样式去确定父子关系,最后初始化得到效果,但大部分情况下,我们的表格数据都不是写死的,而是通过后台获取数据,然后将数据渲染到前端,最终得到我们想要的效果,如果根据组件目前的使用方式,我们得到一个集合数据之后,需要自己去拼接tr、td这些东西,这都是小事,最麻烦的是组件是有父子关系的,我们需要根据我们数据之间的关系转化为组件的父子关系,并且由于支持无限级,还涉及到数据的递归运算。这个复杂的过程是我们不想经常去做的,怎么办呢?最好的思路就是封装了,封装的时候麻烦一次,以后使用就简单了,可以说这是一件一劳永逸的事情。

(2)一般来说,既然是treegrid,肯定会有表头,而这个表头是根据数据来动态显示的。组件自带的效果可以自己写死表头,但还是那句话,使用的灵活性太差。

由于以上两点,于是才有了今天的这篇文章。

2、组件封装代码示例

首先我们将treegrid组件下载并引用到我们的项目里面,然后向其目录里面加一个extension的文件夹,里面添加一个jquery.treegrid.extension.js的文件。

然后就是最重要的jquery.treegrid.extension.js文件的内容:

(function ($) {
 "use strict";
 $.fn.treegridData = function (options, param) {
 //如果是调用方法
 if (typeof options == 'string') {
 return $.fn.treegridData.methods[options](this, param);
 }
 //如果是初始化组件
 options = $.extend({}, $.fn.treegridData.defaults, options || {});
 var target = $(this);
 debugger;
 //得到根节点
 target.getRootNodes = function (data) {
 var result = [];
 $.each(data, function (index, item) {
 if (!item[options.parentColumn]) {
  result.push(item);
 }
 });
 return result;
 };
 var j = 0;
 //递归获取子节点并且设置子节点
 target.getChildNodes = function (data, parentNode, parentIndex, tbody) {
 $.each(data, function (i, item) {
 if (item[options.parentColumn] == parentNode[options.id]) {
  var tr = $('<tr></tr>');
  var nowParentIndex = (parentIndex + (j++) + 1);
  tr.addClass('treegrid-' + nowParentIndex);
  tr.addClass('treegrid-parent-' + parentIndex);
  $.each(options.columns, function (index, column) {
  var td = $('<td></td>');
  td.text(item[column.field]);
  tr.append(td);
  });
  tbody.append(tr);
  target.getChildNodes(data, item, nowParentIndex, tbody)
 }
 });
 };
 target.addClass('table');
 if (options.striped) {
 target.addClass('table-striped');
 }
 if (options.bordered) {
 target.addClass('table-bordered');
 }
 if (options.url) {
 $.ajax({
 type: options.type,
 url: options.url,
 data: options.ajaxParams,
 dataType: "JSON",
 success: function (data, textStatus, jqXHR) {
  debugger;
  //构造表头
  var thr = $('<tr></tr>');
  $.each(options.columns, function (i, item) {
  var th = $('<th style="padding:10px;"></th>');
  th.text(item.title);
  thr.append(th);
  });
  var thead = $('<thead></thead>');
  thead.append(thr);
  target.append(thead);
  //构造表体
  var tbody = $('<tbody></tbody>');
  var rootNode = target.getRootNodes(data);
  $.each(rootNode, function (i, item) {
  var tr = $('<tr></tr>');
  tr.addClass('treegrid-' + (j + i));
  $.each(options.columns, function (index, column) {
  var td = $('<td></td>');
  td.text(item[column.field]);
  tr.append(td);
  });
  tbody.append(tr);
  target.getChildNodes(data, item, (j + i), tbody);
  });
  target.append(tbody);
  target.treegrid({
  expanderExpandedClass: options.expanderExpandedClass,
  expanderCollapsedClass: options.expanderCollapsedClass
  });
  if (!options.expandAll) {
  target.treegrid('collapseAll');
  }
 }
 });
 }
 else {
 //也可以通过defaults里面的data属性通过传递一个数据集合进来对组件进行初始化....有兴趣可以自己实现,思路和上述类似
 }
 return target;
 };
 $.fn.treegridData.methods = {
 getAllNodes: function (target, data) {
 return target.treegrid('getAllNodes');
 },
 //组件的其他方法也可以进行类似封装........
 };
 $.fn.treegridData.defaults = {
 id: 'Id',
 parentColumn: 'ParentId',
 data: [], //构造table的数据集合
 type: "GET", //请求数据的ajax类型
 url: null, //请求数据的ajax的url
 ajaxParams: {}, //请求数据的ajax的data属性
 expandColumn: null,//在哪一列上面显示展开按钮
 expandAll: true, //是否全部展开
 striped: false, //是否各行渐变色
 bordered: false, //是否显示边框
 columns: [],
 expanderExpandedClass: 'glyphicon glyphicon-chevron-down',//展开的按钮的图标
 expanderCollapsedClass: 'glyphicon glyphicon-chevron-right'//缩起的按钮的图标
 };
})(jQuery);

代码说明

1、为了避免和源组件的初始化冲突,我们自定义的组件取了一个别名,叫 treegridData 。我们使用组件的时候就通过treegridData来进行初始化,如果你觉得这个名称不顺眼,可以自行修改。

2、代码的封装思路基本是参考博主之前介绍组件的封装 https://www./article/112472.htm这一篇里面的内容来的。

3、defaults里面就是初始化组件的时候可以传递的参数,上述注释基本上写得比较清楚。id和parentId两个参数主要是用来描述数据之间的父子级关系,后面我们介绍组件时候的时候你一看就能明白。

4、博主加了几个自认为很有用的属性和方法,应该能减少一些使用的麻烦。比如初始化组件的时候是否展开所有的子节点、添加title、表格行的渐变色和表格边框等。

5、上述封装里面递归查找子节点的时候,每一次都需要遍历所有的数据去找子节点,效率偏低,如果你使用了类似linq to js之类的组件去操作js的集合,可以优化那部分代码,适当提高递归的效率。当然,如果你的结果集本身数据量不太大,这么写影响也不太大。

3、封装后的组件使用

我们在界面上面引用需要的css和js文件  

 <link href="~/Content/bootstrap/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet" />
 <link href="~/Content/jquery-treegrid-master/css/jquery.treegrid.css" rel="external nofollow" rel="stylesheet" />
   <script src="~/Scripts/jquery-1.10.2.min.js"></script>
 <script src="~/Content/bootstrap/js/bootstrap.min.js"></script>
 <script src="~/Content/jquery-treegrid-master/js/jquery.treegrid.min.js"></script>
 <script src="~/Content/jquery-treegrid-master/js/jquery.treegrid.bootstrap3.js"></script>
 <script src="~/Content/jquery-treegrid-master/extension/jquery.treegrid.extension.js"></script>

然后定义一个空的table标签

<table id="tb" ></table>

最后就是js初始化了

$(document).ready(function () {
 $('#tb').treegridData({
 id: 'Id',
 parentColumn: 'ParentId',
 type: "GET", //请求数据的ajax类型
 url: '/TestMVC/GetData', //请求数据的ajax的url
 ajaxParams: {}, //请求数据的ajax的data属性
 expandColumn: null,//在哪一列上面显示展开按钮
 striped: true, //是否各行渐变色
 bordered: true, //是否显示边框
 //expandAll: false, //是否全部展开
 columns: [
  {
  title: '机构名称',
  field: 'Name'
  },
  {
  title: '机构描述',
  field: 'Desc'
  }
 ]
 });
 });

当然啦,还得配上后台的取数据的方法

public class TestMVCController : Controller
 {public JsonResult GetData()
 {
 var result = new List<object>();
 result.Add(new { Id = 1, Name = "百度科技", Desc = "搜索巨头"});
 result.Add(new { Id = 2, Name = "百度事业部", Desc = "搜索巨头",ParentId=1 });
 result.Add(new { Id = 3, Name = "百度人事部", Desc = "搜索巨头", ParentId = 1 });
 result.Add(new { Id = 11, Name = "百度HH部", Desc = "搜索巨头", ParentId = 2 });
 result.Add(new { Id = 4, Name = "百度行政", Desc = "搜索巨头", ParentId = 1 });
 result.Add(new { Id = 5, Name = "百度YY部", Desc = "搜索巨头", ParentId = 1 });
 result.Add(new { Id = 12, Name = "百度BB部", Desc = "搜索巨头", ParentId = 2 });
 result.Add(new { Id = 6, Name = "搜狐科技", Desc = "IT" });
 result.Add(new { Id = 7, Name = "搜狐信息部", Desc = "IT", ParentId = 6 });
 result.Add(new { Id = 8, Name = "搜狐人事", Desc = "IT", ParentId = 6 });
 result.Add(new { Id = 9, Name = "搜狐事业部", Desc = "IT", ParentId = 6 });
 result.Add(new { Id = 10, Name = "搜狐事业子部", Desc = "IT", ParentId = 9 });
 return Json(result, JsonRequestBehavior.AllowGet);
 }
 }

这里一看应该就能明白组件defaults里面的id和parentColumn的作用了吧。记得jqgrid里面使用treeview的时候用到了一个level用来判断是哪一级别的节点,博主觉得这样硬性要求返回数据里面加一个level属性有点不妥,所以我们约定如果当前记录的parentId为null或者空字符串的时候,这个节点就是根节点,然后根据根节点去递归找子节点。

使用后的各种效果示例如下。

初始化的时候配置expandAll: false得到的效果

增加隔行变色striped: true

增加表格边框bordered: true

综合效果

三、总结

至此本文就结束了,没有什么太高大上的技术,就是简单将一个第三方组件进行了一些封装,使得其使用起来更加方便而已。如果你项目中也正在为treegrid而纠结,何不试试呢。其实扩展bootstrapTable的treegrid功能的思路博主已经有了,等有时间在下篇给出说明。

以上所述是小编给大家介绍的JS 组件系统之 bootstrap treegrid 组件封装过程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# bootstrap  # treegrid  # js  # 组件  # bootstrap table表格插件使用详解  # Angualrjs和bootstrap相结合实现数据表格table  # bootstrap table实现单击单元格可编辑功能  # BootstrapTable refresh 方法使用实例简单介绍  # bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法  # bootstrap——bootstrapTable实现隐藏列的示例  # JS 组件系列之BootstrapTable的treegrid功能  # 递归  # 搜狐  # 就能  # 开源  # 的是  # 如果你  # 在此  # 太大  # 自带  # 涉及到  # 第三方  # 渐变色  # 小编  # 最原始  # 这是  # 组织架构  # 几个  # 这一  # 文档  # 也不 


相关文章: 自助网站制作软件,个人如何自助建网站?  教程网站设计制作软件,怎么创建自己的一个网站?  潮流网站制作头像软件下载,适合母子的网名有哪些?  如何在IIS7中新建站点?详细步骤解析  建站之星展会模版如何一键下载生成?  如何快速生成凡客建站的专业级图册?  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  Android自定义控件实现温度旋转按钮效果  建站主机选购指南:核心配置优化与品牌推荐方案  商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?  太平洋网站制作公司,网络用语太平洋是什么意思?  相册网站制作软件,图片上的网址怎么复制?  c# 在ASP.NET Core中管理和取消后台任务  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  微信h5制作网站有哪些,免费微信H5页面制作工具?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  如何用PHP快速搭建CMS系统?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  html制作网站的步骤有哪些,iapp如何添加网页?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  宝塔建站后网页无法访问如何解决?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  移民网站制作流程,怎么看加拿大移民官网?  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  香港网站服务器数量如何影响SEO优化效果?  如何在建站之星网店版论坛获取技术支持?  简易网站制作视频教程,使用记事本编写一个简单的网页html文件?  建站为何优先选择香港服务器?  微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  ,制作一个手机app网站要多少钱?  php8.4新语法match怎么用_php8.4match表达式替代switch【方法】  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何快速搭建高效简练网站?  python的本地网站制作,如何创建本地站点?  网站制作免费,什么网站能看正片电影?  如何访问已购建站主机并解决登录问题?  非常酷的网站设计制作软件,酷培ai教育官方网站?  定制建站流程步骤详解:一站式方案设计与开发指南  建站之星与建站宝盒如何选择最佳方案?  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  建站之星安装后如何自定义网站颜色与字体?  网站制作服务平台,有什么网站可以发布本地服务信息?  建站之星如何快速生成多端适配网站?  建站之星北京办公室:智能建站系统与小程序生成方案解析  如何获取免费开源的自助建站系统源码?  建站之星会员如何解锁更多建站功能?  建站主机与虚拟主机有何区别?如何选择最优方案?  网站制作的方法有哪些,如何将自己制作的网站发布到网上? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。