c#--js--樹形菜單(幾種常見樹形菜單)

  • 一開始使用了jstree,因爲簡約風格挺好看,結果開始做動態數據時,發現api太少,效果也太少,節點想添加個鏈接跳轉都查了好久的資料,愣是沒找到好用的。
  • 然後又去看了一下 zTree,發現demo裏有 帶鏈接的實例,而且有種metro風格和 jstree效果挺相似,果斷棄 jstree選擇了 ztree,畢竟可以拿過來直接用,而且api很詳細,demo也豐富。就是json格式沒有介紹太詳細。不過查資料找到很多ztree關於 json格式的介紹,nice
  • 兩種插件都支持 標準json格式和 簡單json格式,只是寫法上有細微不同,如下兩圖

zTree 的 簡單 json格式在這裏插入圖片描述jstree的 簡單 json格式
在這裏插入圖片描述

1.zTree 簡介

官網:http://www.treejs.cn/v3/demo.php#_101
引用的js和css文件下載地址:https://gitee.com/zTree/zTree_v3

.
支持的json格式:標準格式和簡單格式,,(推薦使用簡單(平級)的json數據結構,如下圖)在這裏插入圖片描述在這裏插入圖片描述
.
zTree 是一個依靠 jQuery 實現的多功能 “樹插件”。優異的性能、靈活的配置、多種功能的組合是 zTree 最大優點。
zTree 是開源免費的軟件(MIT 許可證)。如果您對 zTree 感興趣或者願意資助 zTree 繼續發展下去,可以進行捐助。

zTree v3.0 將核心代碼按照功能進行了分割,不需要的代碼可以不用加載
採用了 延遲加載 技術,上萬節點輕鬆加載,即使在 IE6 下也能基本做到秒殺
兼容 IE、FireFox、Chrome、Opera、Safari 等瀏覽器
支持 JSON 數據
支持靜態 和 Ajax 異步加載節點數據
支持任意更換皮膚 / 自定義圖標(依靠css)
支持極其靈活的 checkbox 或 radio 選擇功能
提供多種事件響應回調
靈活的編輯(增/刪/改/查)功能,可隨意拖拽節點,還可以多節點拖拽喲
在一個頁面內可同時生成多個 Tree 實例
簡單的參數配置實現 靈活多變的功能

在這裏插入圖片描述
實例下載地址:
js樹形控件—zTree使用(推薦,看一看,有 zTree支持的幾種json格式)
zTree – jQuery 樹插件 構造treeNode JSON 數據對象
zTree – jQuery 樹插件 使用方法與例子
超級詳細的Ztree詳解
jQuery樹形菜單插件zTree(實例下載)
C#動態加載樹菜單
使用ztree.js,受益一生,十分鐘學會使用tree樹形結構插件

2.jsTree

官網:https://www.jstree.com.cn/
實例:http://www.jq22.com/jquery-info5724
引用的js和css文件下載地址:https://www.jstree.com.cn/
.
支持的json格式:標準格式和簡單格式,,(推薦使用簡單(平級)的json數據結構,如下圖)
(推薦使用平級的json數據結構)
在這裏插入圖片描述
支持的幾種JSON格式:https://www.jstree.com.cn/docs/json.html

jsTree 是一個jquery 插件, 提供交互式樹.它是完全免費的,開源的,並根據MIT許可進行分發。jsTree易於擴展,可定義和配置,它支持HTML和JSON數據源以及AJAX加載。

jsTree可以在盒子模型(內容框或邊框)中正常運行,可以作爲AMD模塊加載,並具有用於響應式設計的內置移動主題,可以輕鬆自定義。它使用jQuery的事件系統,因此對樹中各種事件的綁定回調是熟悉且容易的。

僅有的一些功能值得注意:

拖放支持 鍵盤導航 內聯編輯,創建和刪除 三態複選框 模糊搜索 可定製的節點類型 

在這裏插入圖片描述
Chrome 14+, Firefox 3.5+, Opera 12+, Safari 4+, IE8+
以上的舊版本可能可以運行,但未經測試

參考:
jsTree (js 實現多級菜單+點擊節點頁面跳轉)
JsTree 最詳細教程及完整實例
jstree – 使用JSON 數據組裝成樹
.
.
.
.

======================== 以下爲 zTree 的 metro風格 官方實例============================
======================== 以下爲 zTree 的 metro風格 官方實例============================
======================== 以下爲 zTree 的 metro風格 官方實例============================
.
參考 前端框架inspinia裏的樹形菜單效果,重新定義了部分效果(行高改爲24px,字體大小改爲13px,選中效果改爲 淺藍色帶陰影),修改內容在下面<style>......</style>
引用的js和css文件下載地址:https://gitee.com/zTree/zTree_v3

<!DOCTYPE html>
<HTML>
<HEAD>
    <TITLE> ZTREE DEMO - Simple Data</TITLE>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" href="../../../css/demo.css" type="text/css">
    <link rel="stylesheet" href="../../../css/metroStyle/metroStyle.css" type="text/css">
    <script type="text/javascript" src="../../../js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="../../../js/jquery.ztree.core.js"></script>
    <script type="text/javascript" src="../../../js/jquery.ztree.excheck.js"></script>
    <script type="text/javascript" src="../../../js/jquery.ztree.exedit.js"></script>
    <style>
        /*參考 前端框架inspinia裏的樹形菜單效果,重新修改樣式*/
        /*metroStyle.css 13行*/
        .ztree li {  
            line-height: 24px !important;   
        }
         /*metroStyle.css 11行*/
        .ztree * {
            font-size: 13px !important;
        }
         /*metroStyle.css 19行*/
        .ztree li a.curSelectedNode {
            /*background-color: #e5e5e5;*/
            background: #beebff;
            border-radius: 6px;
            box-shadow: inset 0 0 5px #999;
        }
    </style>
    <SCRIPT type="text/javascript">
        <!--
        var setting = {
            view: {
                addHoverDom: addHoverDom,
                removeHoverDom: removeHoverDom,
                selectedMulti: false
            },
            check: {
                enable: true
            },
            data: {
                simpleData: {
                    enable: true
                }
            },
            edit: {
                enable: true
            }
        };

        var zNodes =[
            { id:1, pId:0, name:"父節點1", open:true},
            { id:11, pId:1, name:"父節點11"},
            { id:111, pId:11, name:"葉子節點111"},
            { id:112, pId:11, name:"葉子節點112"},
            { id:113, pId:11, name:"葉子節點113"},
            { id:114, pId:11, name:"葉子節點114"},
            { id:12, pId:1, name:"父節點12"},
            { id:121, pId:12, name:"葉子節點121"},
            { id:122, pId:12, name:"葉子節點122"},
            { id:123, pId:12, name:"葉子節點123"},
            { id:124, pId:12, name:"葉子節點124"},
            { id:13, pId:1, name:"父節點13", isParent:true},
            { id:2, pId:0, name:"父節點2"},
            { id:21, pId:2, name:"父節點21", open:true},
            { id:211, pId:21, name:"葉子節點211"},
            { id:212, pId:21, name:"葉子節點212"},
            { id:213, pId:21, name:"葉子節點213"},
            { id:214, pId:21, name:"葉子節點214"},
            { id:22, pId:2, name:"父節點22"},
            { id:221, pId:22, name:"葉子節點221"},
            { id:222, pId:22, name:"葉子節點222"},
            { id:223, pId:22, name:"葉子節點223"},
            { id:224, pId:22, name:"葉子節點224"},
            { id:23, pId:2, name:"父節點23"},
            { id:231, pId:23, name:"葉子節點231"},
            { id:232, pId:23, name:"葉子節點232"},
            { id:233, pId:23, name:"葉子節點233"},
            { id:234, pId:23, name:"葉子節點234"},
            { id:3, pId:0, name:"父節點3", isParent:true}
        ];

        $(document).ready(function(){
            $.fn.zTree.init($("#treeDemo"), setting, zNodes);
        });

        var newCount = 1;
        function addHoverDom(treeId, treeNode) {
            var sObj = $("#" + treeNode.tId + "_span");
            if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
            var addStr = "<span class='button add' id='addBtn_" + treeNode.tId
                + "' title='add node' οnfοcus='this.blur();'></span>";
            sObj.after(addStr);
            var btn = $("#addBtn_"+treeNode.tId);
            if (btn) btn.bind("click", function(){
                var zTree = $.fn.zTree.getZTreeObj("treeDemo");
                zTree.addNodes(treeNode, {id:(100 + newCount), pId:treeNode.id, name:"new node" + (newCount++)});
                return false;
            });
        };
        function removeHoverDom(treeId, treeNode) {
            $("#addBtn_"+treeNode.tId).unbind().remove();
        };
        //-->
    </SCRIPT>
</HEAD>

<BODY>
<h1>Metro 風格</h1>
<h6>[ 文件路徑: super/metro.html ]</h6>
<div class="content_wrap">
    <div class="zTreeDemoBackground left">
        <ul id="treeDemo" class="ztree"></ul>
    </div>
    <div class="right">
        <ul class="info">
            <li class="title"><h2>1、樣式文件說明</h2>
                <ul class="list">
                    <li class="highlight_red">請使用 css/metroStyle 目錄內的樣式文件 和 圖片</li>
                    <li>感謝網友 rqx110 提供, 僅供參考</li>
                    <li>參考 前端框架inspinia裏的樹形菜單效果,重新定義了部分效果(行高改爲24px,字體大小改爲13px,選中效果改爲 淺藍色帶陰影),修改內容在上面</li>
</ul>
            </li>
        </ul>
    </div>
</div>
</BODY>
</HTML>

================================== 以下爲zTree擴展============================
================================== 以下爲zTree擴展============================
================================== 以下爲zTree擴展============================

C#之生成樹形菜單數據

https://www.cnblogs.com/zengnansheng/p/10389376.html
.
.

js樹形控件—zTree使用

原文:https://blog.csdn.net/qq_35934094/article/details/80852989?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

0 zTree簡介

樹形控件的使用是應用開發過程中必不可少的。zTree 是一個依靠 jQuery 實現的多功能 “樹插件”。優異的性能、靈活的配置、多種功能的組合是 zTree 最大優點。

0.0 zTree的特點

最新版的zTree將核心代碼按照功能進行了分割,不需要的代碼可以不用加載,如普通使用只需要加載核心的jquery.ztree.core-3.5.js,需要使用勾選功能加載jquery.ztree.excheck-3.5.min.js,需要使用編輯功能加載jquery.ztree.exedit-3.5.min.js
採用了延遲加載技術,上萬節點輕鬆加載,即使在 IE6 下也能基本做到秒殺
兼容 IE、FireFox、Chrome、Opera、Safari 等瀏覽器
支持 JSON 數據
支持靜態 和 Ajax 異步加載節點數據
支持任意更換皮膚 / 自定義圖標(依靠css)
支持極其靈活的 checkbox 或 radio 選擇功能
提供多種事件響應回調
靈活的編輯(增/刪/改/查)功能,可隨意拖拽節點,還可以多節點拖拽
在一個頁面內可同時生成多個 Tree 實例
簡單的參數配置實現,靈活多變的功能

0.1 zTree文件介紹

從zTree官網下載的zTree包括以下組成部分

metroStyle文件夾:zTree的metro風格樣式相關文件(圖片及css樣式表)。
zTreeStyle文件夾:zTree的標準風格樣式文件夾(圖片及css樣式表)
js文件:zTree.all.js是完整的js庫,可單純加載此文件實現所有zTree功能,ztree.core、ztree.excheck、ztree.exedit、ztree.exhide是對ztree按照功能進行的分割,分別對應基本功能、複選功能、編輯功能、顯隱功能。

1 zTree的基本使用

1.0 zTree的創建

在頁面中添加對zTree的js及css引用,由於zTree基於JQuery,JQuery的引用是必須的。

<!DOCTYPE html>
<HTML>
<HEAD>
 <TITLE> ZTREE DEMO </TITLE>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <link rel="stylesheet" href="zTreeStyle/zTreeStyle.css" type="text/css">
 <script type="text/javascript" src="jquery-1.4.2.js"></script>
 <script type="text/javascript" src="jquery.ztree.core-3.x.js"></script>
 <SCRIPT LANGUAGE="JavaScript">
  var zTreeObj;
  var setting = {};  // zTree 的參數配置,後面詳解
   var zNodes = [   // zTree 的數據屬性,此處使用標準json格式
   {
   name: "test1", open: true, children: [
   { name: "test1_1" }, { name: "test1_2" }]
  },
  {
   name: "test2", open: true, children: [
   { name: "test2_1" }, { name: "test2_2" }]
  }
  ];
  $(document).ready(function () {
   zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes); //初始化zTree,三個參數一次分別是容器(zTree 的容器 className 別忘了設置爲 "ztree")、參數配置、數據源
  });
 </SCRIPT>
</HEAD>
<BODY>
 <div>
  <ul id="treeDemo" class="ztree"></ul>
 </div>
</BODY>
</HTML>

運行結果如下

1.1 zTree的配置

zTree的配置採用Json格式,按照配置的類型分爲view(可視界面相關配置)、data(數據相關配置)、check(複選框相關配置)、callback(各類事件的回調函數配置)、async(zTree異步加載配置),一下是我們經常會使用到的一些配置及說明,其他詳細配置可以參考zTree官方API文檔的詳細介紹。

var setting = {
   view: {
    selectedMulti: true, //設置是否能夠同時選中多個節點
    showIcon: true,  //設置是否顯示節點圖標
    showLine: true,  //設置是否顯示節點與節點之間的連線
    showTitle: true,  //設置是否顯示節點的title提示信息
   },
   data: {
     simpleData: {
     enable: false, //設置是否啓用簡單數據格式(zTree支持標準數據格式跟簡單數據格式,上面例子中是標準數據格式)
      idKey: "id",  //設置啓用簡單數據格式時id對應的屬性名稱
      pidKey: "pId" //設置啓用簡單數據格式時parentId對應的屬性名稱,ztree根據id及pid層級關係構建樹結構
    }
   },
   check:{
    enable: true   //設置是否顯示checkbox複選框
   },
   callback: {
    onClick: onClick,    //定義節點單擊事件回調函數
    onRightClick: OnRightClick, //定義節點右鍵單擊事件回調函數
    beforeRename: beforeRename, //定義節點重新編輯成功前回調函數,一般用於節點編輯時判斷輸入的節點名稱是否合法
    onDblClick: onDblClick,  //定義節點雙擊事件回調函數
    onCheck: onCheck    //定義節點複選框選中或取消選中事件的回調函數
   },
   async: {
    enable: true,      //設置啓用異步加載
    type: "get",      //異步加載類型:post和get
    contentType: "application/json", //定義ajax提交參數的參數類型,一般爲json格式
    url: "/Design/Get",    //定義數據請求路徑
    autoParam: ["id=id", "name=name"] //定義提交時參數的名稱,=號前面標識節點屬性,後面標識提交時json數據中參數的名稱
   }
  };

需要注意的是,zTree的事件回調部分,基本上每一個事件都對應一個beforeXXX事件,比如onClick事件對應有一個beforeOnClick事件,主要用於控制相關事件是否允許執行,如果before事件返回false,則取消執行對應相關事件。

1.2 zTree的數據格式

zTree的每一個節點都是一個treeNode對象,treeNode對象經常用到的屬性和方法如下:

treeNode: {
    name,  //節點顯示的文本
    checked, //節點是否勾選,ztree配置啓用複選框時有效
    open,  //節點是否展開
    icon,  //節點的圖標
    iconOpen, //節點展開式的圖標
    iconClose, //節點摺疊時的圖標
    id,   //節點的標識屬性,對應的是啓用簡單數據格式時idKey對應的屬性名,並不一定是id,如果setting中定義的idKey:"zId",那麼此處就是zId
    pId,  //節點parentId屬性,命名規則同id
    children, //得到該節點所有孩子節點,直接下級,若要得到所有下屬層級節點,需要自己寫遞歸得到
    isParent, //判斷該節點是否是父節點,一般應用中通常需要判斷只有葉子節點才能進行相關操作,或者刪除時判斷下面是有子節點時經常用到。
    getPath() //得到該節點的路徑,即所有父節點,包括自己,此方法返回的是一個數組,通常用於創建類似麪包屑導航的東西A-->B-->C
   }

zTree的數據源一般有標準數據格式、簡單數據格式兩種,標準數據格式通過指定節點的chidren屬性構建層級關係,而簡單數據格式根據根據id,pid屬性構建層級關係,我們在應用開發中使用關係型數據庫,一般採用的都是簡單數據格式。

標準數據格式

var nodes = [
 {name: "父節點1", children: [
  {name: "子節點1"},
  {name: "子節點2"}
 ]}
];

簡單數據格式

var nodes = [
 {id:1, pId:0, name: "父節點1"},
 {id:11, pId:1, name: "子節點1"},
 {id:12, pId:1, name: "子節點2"}
];

注意zTree的默認配置是不啓用簡單數據格式,使用簡單數據格式一定要在setting中進行簡單數據格式的相關配置。

1.3 zTree的常用方法

zTree的主要操作方法介紹如下

獲取zTree對象

var treeObj = $.fn.zTree.getZTreeObj("tree");

增加節點

addNodes(parentNode,index,newNodes,isSlient)

parentNode:指定的父節點,如果增加根節點,請設置 parentNode 爲 null 即可

index:新節點插入的位置(從 0 開始),index = -1 時,插入到最後,此參數可忽略

newNodes:需要增加的節點數據 JSON 對象集合,數據只需要滿足 zTree 的節點數據必需的屬性即可

isSilent:true 時,添加節點後不展開父節點,其他值或缺省狀態都自動展開

勾選或取消勾選全部節點

checkAllNodes(checked);

checked參數爲true時全部勾選,爲false時全部取消勾選。

勾選或取消勾選單個節點

checkNode(node, checked, checkedTypeFlag,callbackFlag);

node:要進行操作的節點

checked:爲true勾選,爲false取消勾選

checkeTypeFlag:爲true表示對當前結點的子節點及父節點進行勾選狀態的聯動,爲false不聯動

callbackFlag:爲true時表示執行beforeOnCheck和onCheck事件的回調函數,爲false不執行

編輯節點

edit(node); 使節點處於編輯狀態,必須引用jquery.ztree.exedit 擴展。

展開或摺疊全部節點

expandAll(expand);

expand爲true是展開所有節點,爲false是摺疊所有節點。

根據節點屬性查找結點

getNodesByParam(key,value, parentNode);

key:屬性名

value:屬性值

parentNode:是否在指定節點下查找,爲null表示整個樹查找。

獲取被勾選或未被勾選的節點集合

getCheckedNodes(checked);

checked爲true表示獲取所有被勾選的節點集合,爲false表示所有未被勾選的節點集合

獲取輸入框勾選狀態被改變的節點集合

getChangeCheckedNodes()

2 zTree的常用操作

2.0 ajax請求數據並創建zTree

$(function () {
   var setting = {     //此處根據自己需要進行配置
    view: {
     selectedMulti: false
    },
    data: {
     simpleData: {
      enable: true
     }
    },
    callback: {
     onClick: onDesignTreeClick,
     onRightClick: OnRightClick,
     beforeRename: beforeRename,
     onCheck:onCheck
    }
   };
   $.ajax({
    type: "Get",
    url: "/Design/GetDesignTreeData",     //ajax請求地址
     success: function (data) {
     $.fn.zTree.init($("#treeZo"), setting, data); //加載數據
    },
   });
  });

後臺代碼如下,可以根據需要返回你想要的任何數據,綁定到zTree上,然後通過treeNode.屬性名取到對應的值,實現一些界面邏輯操作。

public ActionResult GetDesignTreeData()
 {
  var result = _designAppService.GetDesignTreeData();
  List<ModelTreeViewModel> treeModels = new List<ModelTreeViewModel>();
  bool open = false;
  foreach (var design in result.Designs)
  {
   if (design.ParentId == Guid.Empty)
    open = true;
   else open = false;
   treeModels.Add(new ModelTreeViewModel() { Id = design.Id.ToString(), PId = design.ParentId.ToString(), Name = design.Name, Open = open, Data = design.Remarks ?? "", ViewPoint = design.ViewPoint ?? "", Checked = true });
  }
  return Json(treeModels, JsonRequestBehavior.AllowGet);
 }

2.1 節點單擊操作

節點單擊事件會捕獲事件對象e,zTree的唯一標識treeId,當前選中的節點對象treeNode三個參數。根據實際需求可獲取treeNode中包含的任何屬性數據,進行相關操作

function onClick(e, treeId, treeNode) {
   if (treeNode.isParent) //如果不是葉子結點,結束
    return;
   alert(treeNode.name); //獲取當前結點上的相關屬性數據,執行相關邏輯
  };

2.2 節點複選框事件

一般情況下我們會直接使用treeObj.getCheckedNodes(true);獲取所有選中的節點,然後遍歷所有選中的節點進行相關操作,當面對大數據量時,這種操作方法便不可取,可通過getChangeCheckedNodes()方法獲取勾選狀態被改變的節點集合,值針對狀態改變的節點做相應處理。

function onCheck() {
var treeObj = $.fn.zTree.getZTreeObj(“treeDemo”); //獲取樹對象
var nodes = treeObj.getChangeCheckedNodes(); //獲取勾選狀態改變的節點
var designIds = [];
var status = 0; //定義初始勾選狀態爲未勾選
if (nodes[0].checked)
status = 1; //如果狀態改變節點爲勾選狀態,說明當前操作是從未勾選變爲已勾選。
$.each(nodes, function (i, item) {
designIds.push(item.id); //將狀態改變的節點id輸出到數組
item.checkedOld = item.checked; //這句話很關鍵,將節點的初始狀態置爲當前狀態。否則每次勾選操作獲取狀態改變節點時只會跟樹初始化的狀態相比較。
})
$.ajax({
type: “Post”,
url: “/Design/GetRelationComponentIdsByDesigns”,
data: { “designIds”: designIds },
success: function (data) {
RealBimOcx.BatchAddSubClrInfoBegin();
$.each(data.result, function (i, item) {
if (status == 1) //這裏根據發生改變的節點是勾選還是爲勾選進行相關邏輯操作。
RealBimOcx.AddSubClrInfo(item, 255, 255, 0);
else
RealBimOcx.AddSubClrInfo(item, 0, 255, 0);
if (i % 100 == 0) {
RealBimOcx.BatchAddSubClrInfoEnd();
RealBimOcx.BatchAddSubClrInfoBegin();
}

})
RealBimOcx.BatchAddSubClrInfoEnd();

}
})
};

2.3 實現zTree的右鍵增刪改操作

首先定義右鍵彈出面板

  • 新增節點
  • 刪除節點
  • 編輯節點
  • 升級
  • 降級
  • 上移
  • 下移
  • 重置節點
  • 展開所有
  • 收起所有

實現zTree右鍵單擊事件回調函數

//右鍵單擊回調函數
function OnRightClick(event, treeId, treeNode) {
$("#treeZo").hide();
if (!treeNode && event.target.tagName.toLowerCase() != “button” && $(event.target).parents(“a”).length == 0) {
zTree.cancelSelectedNode();
showRMenu(“root”, event.clientX, event.clientY); //根據鼠標位置顯示右鍵操作面板
} else if (treeNode && !treeNode.noR) {
zTree.selectNode(treeNode);
showRMenu(“node”, event.clientX, event.clientY);
}
$("#treeZo").show();
}
//根據節點類型,控制右鍵操作菜單哪些可用哪些不可用
function showRMenu(type, x, y) {
$("#rMenu ul").show();
if (type == “root”) {
$("#m_del").hide();
$("#m_edit").hide();
$("#m_left").hide();
$("#m_right").hide();
$("#m_up").hide();
$("#m_down").hide();
$("#m_add").addClass(‘mboder’);
} else {
$("#m_del").show();
$("#m_edit").show();
$("#m_left").show();
$("#m_right").show();
$("#m_up").show();
$("#m_down").show();
$("#m_add").removeClass(‘mboder’);
}
rMenu.css({ “top”: y + “px”, “left”: x + “px”, “visibility”: “visible” });
$(“body”).bind(“mousedown”, onBodyMouseDown);
}
//以藏右鍵面板
function hideRMenu() {
if (rMenu) rMenu.css({ “visibility”: “hidden” });
$(“body”).unbind(“mousedown”, onBodyMouseDown);
}
//單擊頁面其他位置 隱藏右鍵面板
function onBodyMouseDown(event) {
if (!(event.target.id == “rMenu” || $(event.target).parents("#rMenu").length > 0)) {
rMenu.css({ “visibility”: “hidden” });
}
}

新增節點

//增加節點
function addTreeNode() {
hideRMenu();
var name = new Date().getTime(); //利用時間戳生成節點名稱,保證節點名稱唯一
var newNode = {
name: name
};
if (zTree.getSelectedNodes()[0]) {
newNode.checked = zTree.getSelectedNodes()[0].checked;
newNode.pid = zTree.getSelectedNodes()[0].id;
zTree.addNodes(zTree.getSelectedNodes()[0], newNode);
} else {
zTree.addNodes(null, newNode);
}
var node = zTree.getNodeByParam(“name”, name, null); //得到新增加的節點
zTree.selectNode(node); //選中新增加的節點
zTree.editName(node); //讓新增加的節點處於編輯狀態
}

編輯節點

function editTreeNode() {
var nodes = zTree.getSelectedNodes(); //得到選中節點集合
if (nodes && nodes.length > 0) {
var parent = nodes[0].getParentNode(); //得到選中節點的父節點
if (parent) {
nodes[0].pid = parent.id; //如果選中節點父節點存在,將當前結點的pid屬性值設置爲父節點的id
}
zTree.editName(nodes[0]); //讓選中節點處於編輯狀態
}
hideRMenu(); //隱藏右鍵面板
};

節點編輯狀態離開時觸發事件

//編輯並保存節點
function beforeRename(treeId, treeNode, newName, isCancel) {
if (newName.length == 0) { //節點名稱判斷
alert(“不能爲空。”);
return false;
}
else {
$.ajax({ //數據入庫
type: “Post”,
url: “/Design/InsertOrUpdate”,
data: { “dto”: { “Id”: treeNode.id, “ParentId”: treeNode.pid, “Name”: newName } },
success: function (data) {
if (data.result == “Faild”) {
layerAlert(“保存失敗。”);
return false;
}
else {
treeNode.id = data.result; //將返回的id賦值給當前結點
return true;
}

}
});
}
};

刪除節點數據

function removeTreeNode() {
hideRMenu();
var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length > 0) {
if (nodes[0].children && nodes[0].children.length > 0) {
alert(“包含下級,無法刪除。”);
} else {
if (confirm(“該操作會將關聯數據同步刪除,是否確認刪除?”) == true) {
$.ajax({
type: “Post”,
url: “/Design/Delete”,
data: { “id”: nodes[0].id },
success: function (data) {
if (data.result == “Success”) {
zTree.removeNode(nodes[0]);
}
else {
alert(“刪除失敗。”);
}
}
});
};
}
}
};

2.4 一些總結

我們通常使用到樹形控件做授權或關聯類似的操作,一般會先全部取消勾選,然後根據選中的數據關聯對樹控件的複選框進行選中操作,在大數據量時,大約幾萬條數據,全部取消勾選+根據關聯數據勾選相關節點這個操作通過js執行會很慢,這種情況建議在後臺通過關聯關係重新組織zTree需要的數據源,對每條數據(對應樹節點)設置checked屬性,然後再前臺頁面重新加載樹,這種操作速度要快得多。

KaTeX parse error: Expected '}', got '&' at position 94: …treeNode.id + "&̲t=" + new Date(….each(data.result, function (i, item) {
// var node = modelTree.getNodeByParam(“id”, item, null);
// modelTree.checkNode(node, true, true);
//});
.fn.zTree.init(.fn.zTree.init(("#treejian"), setting1, data.result); //改爲重新加載,比js循環勾選速度要快。
}
});

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

C#動態加載樹菜單(上下級的json數據結構)

原文:https://www.cnblogs.com/web100/p/csharp-dyn-tree.html

在做權限系統的時候,需要有一個樹形的菜單。下圖就是一個樹形菜單的樣式
在這裏插入圖片描述
但問題是,我們可以實現寫死的樹形菜單。什麼是寫死的?就是在前臺代碼中寫好要加載的樹形菜單是什麼樣子的。但是我們權限系統的要求是動態加載樹形菜單,也就是根據數據庫裏面表的內容動態加載。

我首先要說的就是數據庫設計,要想動態加載成樹形菜單,數據庫表中就一定要設置父節點ID和自身ID。通過父節點ID判斷自身是屬於哪一級菜單,而通過自身ID判斷其對應的下一級菜單。這是數據庫設計應該注意的地方,如果沒有父節點和自身子節點,那麼就沒辦法實現動態加載樹形菜單。

動態加載樹形菜單的實現利用的zTree。這裏順便提一下,zTree的網站做的真的很好,而且各種類型的zTree做的非常完美。我就是利用zTree來實現的,只不過與之不同的是zTree實現的樹菜單也是在前臺寫好的,我們要做的就是將後臺用數據庫查詢到的代碼拼接成前臺已經寫好的代碼格式。

這是前臺寫好的樹菜單格式:

在這裏插入圖片描述
我們要做的就是將前臺這種樹形菜單格式在後臺拼出來,而在樹形菜單中顯示的菜單名稱是從數據庫中查詢出來的。最開始的時候嘗試拼JSON串,但是事實證明,我失敗了,拼出來的字符串運行的時候根本顯示不出來
在這裏插入圖片描述
拼出的JSON串跟咱們要拼接的格式是不同的,JSON串拼接出來的格式適用於結構比較簡單,這樣利用循環可以將需要的字符串拼接出來。而我們需要的字符串是需要判斷下一級是否有子節點的,這個利用JSON串我沒有實現,只能實現一級菜單,而對應的實現三級菜單我沒有拼出來。很遺憾,但是利用循環、遍歷和DataTable的查詢,最終實現了樹形菜單字符串的拼接。下面是我實現的代碼

這個對應的實現二級菜單的拼接 
public string getTree(string strTree)  
{  
    string Chilstr = "";  
    //獲取DataTable  
    zTreeBLL zTree = new zTreeBLL();  
    DataTable dt = new DataTable();  
    dt = zTree.QueryResource();  
    //查詢父節點有多少條不重複的數據  
    zTreeBLL zTree1 = new zTreeBLL();  
    DataTable dt1 = new DataTable();  
    dt1 = zTree1.QueryParidNum();  
    //父節點只能加到4  
    //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32強制轉換字符,把Object類型轉換成int  
    //{  
    int parentId = 0;  
    //查找第一個父節點有多少個,即初值爲0的父節點  
    DataRow[] rowsP = dt.Select("ParentID=" + parentId);  
    //利用循環將父節點拼接起來  
    for (int i = 0; i < rowsP.Length; i++)  
    {  
        //把rowsP裏面的數值取出來  
        foreach (DataRow drP in rowsP)  
        {  
            string parName = drP["ResourceName"].ToString();  
            //strTree = "[{name:\""+ parName + "\"";  
            strTree = "[{name:\"" + parName + "\"";  
            DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);  
            if (rowsC.Length > 0)  //如果子節點不爲0,則開始拼接子節點的字符串  
            {  
                //利用循環將父節點對應下的子節點串起來                            
                foreach (DataRow drC in rowsC)  
                {  
  
                    string chilName = drC["ResourceName"].ToString();  
                    Chilstr = Chilstr + "{name:\"" + chilName + "\"}";  
                    Chilstr = Chilstr + ",";  
  
                }  
                Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);  
                strTree = strTree + ",children:[" + Chilstr + "]}];";  
            }  
            else  
            {  
                strTree = strTree + "\"}];";  
            }  
        }  
    }  
  
    //    parentId++;  
    //}  
    return strTree;  
}  
這個對應的是多級菜單的拼接 
public string getTree(string strTree)  
       {  
           string Chilstr = "";  
             
           //獲取DataTable  
           zTreeBLL zTree = new zTreeBLL();  
           DataTable dt = new DataTable();  
           dt = zTree.QueryResource();  
           //查詢父節點有多少條不重複的數據  
           zTreeBLL zTree1 = new zTreeBLL();  
           DataTable dt1 = new DataTable();  
           dt1 = zTree1.QueryParidNum();  
           //父節點只能加到4  
           //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32強制轉換字符,把Object類型轉換成int  
           //{  
           int parentId = 0;  
           //查找第一個父節點有多少個,即初值爲0的父節點  
           DataRow[] rowsP = dt.Select("ParentID=" + parentId);  
           //利用循環將父節點拼接起來  
           for (int i = 0; i < rowsP.Length; i++)  
           {  
               //把rowsP裏面的數值取出來  
               foreach (DataRow drP in rowsP)  
               {  
                   string parName = drP["ResourceName"].ToString();  
                   //strTree = "[{name:\""+ parName + "\"";  
                   strTree = "[{name:\"" + parName + "\"";  
                   DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);  
                   if (rowsC.Length > 0)  //如果子節點不爲0,則開始拼接子節點的字符串  
                   {  
                       //利用循環將父節點對應下的子節點串起來                            
                       foreach (DataRow drC in rowsC)  
                       {  
                           string Threestr = "";  
                           //判斷二級菜單下對應的ID,也就是查找三級菜單的ParentID  
                           string chilFollow = drC["ID"].ToString();  
                           //查詢三級菜單  
                           DataRow[] rowsThree = dt.Select("ParentID=" + chilFollow);  
                           //判斷是否存在三級菜單  
                           if (rowsThree.Length > 0)  
                           {  
                                 
                               foreach (DataRow drThree in rowsThree)  
                               {  
                                   string ThreeName = drThree["ResourceName"].ToString();  
                                   Threestr = Threestr + "{name:\""+ThreeName+"\"}";  
                                   Threestr = Threestr + ",";  
                               }  
                               Threestr = Threestr.Remove(Threestr.LastIndexOf(","), 1);  
                               string chilName = drC["ResourceName"].ToString();  
                               Chilstr = Chilstr + "{name:\"" + chilName + "\",children:["+Threestr+"]},";   
                                 
                           }  
                           //如果不存在三級菜單的話直接加載二級菜單  
                           else  
                           {  
                               string chilName = drC["ResourceName"].ToString();  
                               Chilstr = Chilstr + "{name:\"" + chilName + "\"}";  
                               Chilstr = Chilstr + ",";  
                           }  
                             
                       }  
                       Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);  
                       strTree = strTree + ",children:[" + Chilstr + "]}];";   
                   }  
                   else  
                   {  
                       strTree = strTree + "\"}];";  
                   }  
               }  
           }  
           return strTree;  
       }  
 最終實現的效果

在這裏插入圖片描述
在這裏插入圖片描述
其實實現這個例子的方法還有很多種,比如說遞歸。雖然JSON串沒有拼接成功,但是我覺得JSON串是可以實現的。只是鑑於個人能力的緣故最終沒有拼接成功。動態加載樹形菜單終於實現的,但是還有很多需要改進的地方,比如如何將這個方法封裝起來,以至於可以無限的調用沒有缺陷等,這是下一步值得繼續探討的問題。

================================== 以下爲jsTree 擴展============================
================================== 以下爲jsTree 擴展============================
================================== 以下爲jsTree 擴展============================
.

.
jsTree (js 實現多級菜單+點擊節點頁面跳轉)

如圖,通過jsTree實現動態菜單欄

clipboard.png

閱讀jsTree的官方文檔之後,你會知道,它有很多實現方式,我下面使用的是Ajax請求,從後臺獲取json數據返回給jsTree。jsTree的官網:https://www.jstree.com/
點擊頁面的Download按鈕,下載並解壓之後,將dist下的文件都複製到你自己的項目中

clipboard.png

前端html,只保留了關鍵代碼

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<!-- Tell the browser to be responsive to screen width -->
<meta
    content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    name="viewport">
<!-- Bootstrap 3.3.7 -->

<link rel="stylesheet"
    href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
</head>
<body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
        
        <!-- 側邊欄【開始】 -->
        <aside class="main-sidebar" id="main-sidebar">
            <section class="sidebar">
                <ul class="sidebar-menu" data-widget="tree">
                    <li class="header">菜單欄</li>

                </ul>
                <!-- 放置菜單的div -->
                <div class="sidebar-menu box-header" style="margin-top: 10px;"
                    id="menu"></div>
                <img id="sidebar-footer" src="vince/images/QRcode.jpg"
                    style="position: fixed; bottom: 0; width: 200px; height: 200px; padding: 20px;"
                    alt="Logo">
            </section>
        </aside>
        <!-- 側邊欄【結束】 -->
        <div id="content-wrapper"></div>
    </div>

    <!-- jQuery 3 -->
    <!-- <script src="bower_components/jquery/dist/jquery.min.js"></script> -->
    <script src="plugins/jQuery/jquery-2.2.3.min.js"></script>
    <!-- Bootstrap 3.3.7 -->
    <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- jstree -->
    <script type="application/javascript" src="dist/js/jstree.js"></script>
    <script type="text/javascript">
        
        //加載菜單【開始】
        var url = "menu/select";
        $(function() {
            $('#menu')
                    .jstree({
                        "core" : {
                            'data' : {
                                'url' : url,
                                'data' : function(node) {
                                    return node;

                                }
                            },
                            "themes" : {
                                "ellipsis" : true
                            //文字多時省略
                            },

                        },

                        "plugins" : [ "wholerow", "types", "themes" ]
                    })
                    .on(
                            'select_node.jstree',
                            function(event, data) {
                                    //添加點擊標籤的方法
                                loadMainContent(data.node.original.href);
                                
                            });

        });
        //加載菜單【結束】
        function loadMainContent(param) {
            if ($("body").hasClass("sidebar-open")) {
                $(".sidebar-toggle").click();
            }
                $("#content-wrapper").load(param);
            
        }
        
    </script>
</body>
</html>

後臺返回前臺的json格式,根節點的parent一定是“#”否則無法識別,子節點的parent是對應的根節點的id

clipboard.png

數據存儲格式

clipboard.png


以下是幾個 樹形菜單 參考(java的,但是可以借鑑)
https://www.cnblogs.com/linjiqin/archive/2013/06/21/3148066.html

https://blog.csdn.net/qq827245563/article/details/78687856

https://www.cnblogs.com/emily1130/p/5570565.html

https://blog.csdn.net/weixin_39723544/article/details/80735877

https://www.jb51.net/article/122811.htm

原文鏈接:https://blog.csdn.net/qq_42060456/article/details/82788331
————————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章