Cette fois, je vais vous apporter AJAX pour réaliser l'ajout, la suppression et la modification de données uitree hiérarchiques infinies Quelles sont les précautions Ici. sont les cas pratiques. Jetons un coup d'oeil.
Répertoire de lecture
•Niveaux illimités
•Plug-in jstree
•Démo
•Créer Entité de région
•Objet de données Dto qui répond au plug-in jstree
•Conversion de données
•Initialisation pour obtenir les données converties
•Chargement des données de premier plan
•Autres opérations
•Ajouter, supprimer et modifier via les boutons
Notation infinie
Souvent, nous ne sommes pas sûrs du niveau de la relation hiérarchique. cette fois, nous devons utiliser une notation infinie.
En parlant de notation infinie, il faut reparler d'appels récursifs. (On dit que la récursivité fréquente nécessite beaucoup de performances.) Ici, nous devons d'abord concevoir la structure de la table pour stocker des données hiérarchiques infinies. Bien sûr, ce qui suit sont tous les résultats de mes propres manipulations et ne sont pas standards. Si quelqu'un a un meilleur design, n'hésitez pas à m'éclairer.
C'est en fait simple à dire, c'est la relation entre un identifiant et l'identifiant parent.
Par analogie, Id doit être unique et ParenId doit exister dans la colonne Id. De cette façon, nous pouvons obtenir une notation infinie. Ce serait encore plus parfait si nous ajoutions une autre colonne de tri.
plug-in jstree
Adresse officielle : https://www.jstree.com/
Pourquoi utiliser ce plug-in ? Parce qu'il existe une API pratique pour nous permettre d'effectuer la liaison de données et qu'elle prend en charge le déplacement de nœuds pour ajouter, supprimer et modifier, je pense personnellement que cette fonction est assez puissante.
Démo
Nous allons maintenant implémenter des opérations de données hiérarchiques illimitées basées sur le plug-in jstree. En prenant comme exemple le fonctionnement des données régionales, utilisez Code First pour écrire du code de démonstration.
Créer une entité Région
Afin de correspondre à l'identifiant de nœud généré automatiquement par le plug-in , nous utilisons Node ici et ParentNode pour stocker la relation supérieur-subordonné (au lieu de l'identifiant et de l'identifiant parent mentionnés ci-dessus, mais l'effet réel est le même).
/// <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; } }
Satisfaire l'objet de données Dto du plug-in jstree
Afin de s'adapter aux exigences de données du plug jstree -in, nous devons convertir les données ci-dessus en objet de données en forme d'arbre.
/// <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; } }
Conversion des données
#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
Initialiser pour obtenir les données converties
/// <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); }
Les données de base ci-dessus sont presque terminées.
Chargement des données de premier plan
$(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;//返回右键菜单项 } }, }); }); });
Autres opérations
//删除节点 $('#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;//是否展开 } }); }
Bien sûr, pensez à récupérer RegionsId, l'ID de l'entité d'arrière-plan correspondante lors de la modification ou de la suppression.
Utilisez des boutons pour opérer des ajouts, des suppressions et des modifications
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); };
Je crois que vous maîtrisez la méthode après avoir lu le cas dans cet article .Pour des choses plus excitantes, veuillez prêter attention à php Autres articles connexes sur le site chinois !
Lecture recommandée :
L'implémentation AJAX affiche la page avant le chargement
implémentation ajax pour vérifier le nom d'utilisateur et le mot de passe dans la base de données
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!