이 글은 주로 무한 그레이딩과 트리 구조 데이터 추가, 삭제, 수정에 대한 관련 정보를 소개하고 있습니다. 필요하신 분들은 참고하시면 됩니다.
디렉토리 읽기
•무한 그레이딩
•jstree 플러그인
•데모
•Region Entity 생성
•jstree 플러그인에 맞는 데이터 객체 Dto
•데이터 변환
•변환된 데이터를 얻기 위한 초기화
•포그라운드 데이터 로딩
•기타 작업
•버튼을 통해 추가, 삭제, 수정
무제한 채점
이때 계층 관계의 수준을 확신할 수 없는 경우가 많으므로 무한 채점을 사용해야 합니다.
무한 채점 얘기가 나와서 말인데, 재귀 호출에 대해 다시 이야기해야 합니다. (잦은 재귀는 성능 집약적이라고 합니다.) 여기서는 무한한 계층적 데이터를 저장하기 위해 먼저 테이블 구조를 설계해야 합니다. 물론, 다음은 모두 제가 직접 조작한 결과이며 표준은 아닙니다. 더 나은 디자인을 갖고 계신 분이 계시다면, 저에게 알려주시기 바랍니다.
사실 간단하게 말하면 ID와 부모 ID의 관계입니다.
비유하자면 Id는 고유해야 하며 ParenId는 Id 열에 존재해야 합니다. 이런 식으로 또 다른 Sort 열을 추가하면 무한 등급을 얻을 수 있습니다.
jstree 플러그인
공식 주소: https://www.jstree.com/
왜 이 플러그인을 사용하나요? 데이터 바인딩을 할 수 있는 편리한 API가 있고, 추가, 삭제, 수정을 위한 노드 드래그도 지원하기 때문에 개인적으로 이 기능은 꽤 강력하다고 생각합니다.
Demo
이제 jstree 플러그인을 기반으로 무제한 계층적 데이터 작업을 구현하겠습니다. 지역 데이터 작업을 예로 들어 Code First를 사용하여 데모 코드를 작성합니다.
Create Region 엔터티
플러그인에서 자동으로 생성된 노드 ID를 일치시키기 위해 여기서는 Node 및 ParentNode를 사용하여 상위-하위 관계를 저장합니다(언급된 ID 및 parentid 대신). 위와 같지만 실제 효과는 동일합니다).
/// <summary> /// 区域 /// </summary> public class Region { /// <summary> /// 主键id /// </summary> public int Id { get; set; } /// <summary> /// 名称 /// </summary> public string Name { get; set; } /// <summary> /// 节点 /// </summary> public string Node { get; set; } /// <summary> /// 父节点 /// </summary> public string ParentNode { get; set; } }
jstree 플러그인의 데이터 객체 Dto를 만족합니다
jstree 플러그인의 데이터 요구 사항에 적응하려면 위의 데이터를 트리와 같은 데이터 객체로 변환해야 합니다.
/// <summary> /// Dto /// </summary> public class RegionsTreeOutput { /// <summary> /// Id /// </summary> public int RegionsId { get; set; } /// <summary> /// tree显示文本(对应region的name) /// </summary> public string text { get; set; } /// <summary> /// tree的id(对应Node) /// </summary> public string id { get; set; } /// <summary> /// 子节点数据(此属性就体现的数据的层级关系) /// </summary> public List<RegionsTreeOutput> children { get; set; } }
데이터 변환
#region GetRegionTree 初始化数据获取 的辅助方法 public RegionsTreeOutput LoadRegions(string id, List<Region> inRegions, RegionsTreeOutput outRegions) { List<Region> regions = inRegions.Where(t => t.ParentNode == id).ToList(); if (outRegions == null)//加载父节点 { outRegions = ToTreeData(regions[0]); LoadRegions(outRegions.id, inRegions, outRegions); } else//加载子节点 { outRegions.children = ToTreesData(regions); if (regions.Count > 0) { for (int i = 0; i < regions.Count; i++) { LoadRegions(regions[i].Node, inRegions, outRegions.children[i]);//递归调用 } } } return outRegions; } public RegionsTreeOutput ToTreeData(Region region) { var treeData = new RegionsTreeOutput(); treeData.id = region.Node; treeData.text = region.Name; treeData.RegionsId = region.Id; return treeData; } public List<RegionsTreeOutput> ToTreesData(List<Region> listRegion) { var regions = new List<RegionsTreeOutput>(); for (int i = 0; i < listRegion.Count; i++) { regions.Add(ToTreeData(listRegion[i])); } return regions; } #endregion
변환된 데이터를 얻기 위한 초기화
/// <summary> /// 初始化数据获取 /// </summary> /// <returns></returns> public JsonResult GetResultData() { TreeDbContext db = new TreeDbContext(); var regions = db.Regions.Where(t => true).ToList(); var regionObj = LoadRegions("-1", regions, null); return Json(regionObj); }
위의 백그라운드 데이터가 거의 완성되었습니다.
포그라운드 데이터 로딩
$(function () { $.post("/Home/GetResultData", null, function (sData) { treeObj = $('#jstree_demo').jstree({ //, "checkbox" 'plugins': ["contextmenu", "dnd", "search", "state", "types", "wholerow"], 'core': { "animation": 0, "check_callback": true, 'force_text': true, "themes": { "stripes": true }, 'data': sData }, "types": { "default": { "icon": "fa fa-folder icon-state-warning icon-lg" }, "file": { "icon": "fa fa-file icon-state-warning icon-lg" } }, "contextmenu": { select_node: false, show_at_node: true, items: function (o, cb) { //因为这里我们之后需要定义多个项,所以通过对象的方式返回 var actions = {}; //添加一个"新增"右键菜单 actions.create = {//这里的create其实阔以随意命名,关键是里面的 这里面的 action回调方法 "separator_before": false,//Create这一项在分割线之前 "separator_after": true,//Create这一项在分割线之后 "_disabled": false, //false表示 create 这一项可以使用; true表示不能使用 "label": "新增", //Create这一项的名称 可自定义 "action": function (data) { //点击Create这一项触发该方法,这理还是蛮有用的 var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference);//获得当前节点,可以拿到当前节点所有属性 //新加节点,以下三行代码注释掉就不会添加节点 inst.create_node(obj, {}, "last", function (new_node) { setTimeout(function () { inst.edit(new_node); }, 0);//新加节点后触发 重命名方法,即 创建节点完成后可以立即重命名节点 }); } }; if (o.id != "0001")//屏蔽对根节点的操作 “0001”改成根节点对应的真是id { //添加一个"重命名"右键菜单 actions.rename = { "separator_before": false, "separator_after": false, "_disabled": false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), "label": "重命名", "action": function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.edit(obj); } } //添加一个"删除"右键菜单 actions.delete = { "separator_before": false, "icon": false, "separator_after": false, "_disabled": false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), "label": "删除", "action": function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if (inst.is_selected(obj)) { inst.delete_node(inst.get_selected()); } else { inst.delete_node(obj); } } }; } return actions;//返回右键菜单项 } }, }); }); });
기타 작업
//删除节点 $('#jstree_demo').on('delete_node.jstree', function (e, data) { var id = data.node.original.RegionsId; $.ajax({ type: "get", url: "/Home/DeleteRegion?id=" + id, success: function (sData) { } }); }); //移动节点 $('#jstree_demo').on('move_node.jstree', function (e, data) { saveRegions(data); }); //修改名 $('#jstree_demo').on('rename_node.jstree', function (e, data) { saveRegions(data); }); //保存 function saveRegions(data) { var id = data.node.original.RegionsId; var name = data.node.text;//修改后的name //var oldName = data.old;//原name //var pNode = $('#jstree_demo').jstree().get_node(data.node.parent).original.RegionsId; var josnData = { "Id": id, "Node": data.node.id, "ParentNode": data.node.parent, "Name": name }; $.ajax({ url: "/Home/SaveRegions", data: josnData, success: function (sData) { data.node.original.RegionsId = sData; data.node.state.opened = false;//是否展开 } }); }
물론 해당 백그라운드 엔터티인 RegionsId의 ID를 수정하거나 삭제하는 것을 잊지 마세요.
버튼을 사용하여 추가, 삭제, 수정
function createTree() { var ref = $('#jstree_demo').jstree(true), sel = ref.get_selected(); if (!sel.length) { return false; } sel = sel[0]; sel = ref.create_node(sel, { "type": "file" }); if (sel) { ref.edit(sel); } }; function renameTree() { var ref = $('#jstree_demo').jstree(true), sel = ref.get_selected(); if (!sel.length) { return false; } sel = sel[0]; ref.edit(sel, function () { }); }; function deleteTree() { var ref = $('#jstree_demo').jstree(true), sel = ref.get_selected(); if (!sel.length) { return false; } ref.delete_node(sel); };
위 내용은 제가 모두를 위해 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.
관련 기사:
Ajax를 클릭하면 데이터 목록을 지속적으로 로드할 수 있습니다(그래픽 튜토리얼)
Ajax+Struts2를 사용하여 인증 코드 확인 기능을 구현합니다(그래픽 튜토리얼)
위 내용은 무제한 계층 및 트리 구조 데이터 추가, 삭제 및 수정의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!