jqGrid از نمایش دو ساختار درختی Nested Set model و Adjacency model پشتیبانی میکند. توضیحات تکمیلی و پایهای را در مورد این دو روش مدل سازی اطلاعات، در مطلب «SQL Antipattern #2» میتوانید مطالعه کنید.
در اینجا روش Adjacency model را به علت بیشتر مرسوم بودن آن و شباهت بسیار زیاد آن به «مدلهای خود ارجاع دهنده» بررسی خواهیم کرد.
مدل دادهای Adjacency
در حالت ساختار درختی از نوع مجاورت، علاوه بر خواص اصلی یک کلاس، سه خاصیت دیگر نیز باید تعریف شوند:
ParentId که سبب تولید یک مدل خود ارجاع دهنده میشود.
IsNotExpandable به این معنا است که نود جاری آیا قرار است باز شود و فرزندی دارد یا خیر؟ اگر فرزندی ندارد باید مساوی True قرار گیرد.
IsExpanded حالت پیش فرض باز بودن یا نبودن یک نود را مشخص میکند.
نحوهی بازگشت اطلاعات درختی از سمت سرور
در نگارش فعلی jqGrid، در حالت نمایش درختی، مباحث صفحه بندی و مرتب سازی غیرفعال هستند و کدهای مرتبط با آن که در اینجا ذکر شدهاند، فعلا تاثیری ندارند (البته با کمی تغییر در کدهای آن، میتوان این قابلیت را هم فعال کرد. اطلاعات بیشتر).
نکتهی مهم treeGrid، سه پارامتر دیگر هستند که از سمت کلاینت به سرور ارسال میشوند:
nodeid اگر نال بود، یعنی کل اطلاعات ریشهها (مواردی که parentId مساوی نال دارند)، باید واکشی شوند. اگر nodeid مقدار داشت، یعنی فرزند نود جاری قرار است بازگشت داده شود.
n_level مقدار جلو رفتگی نمایش اطلاعات یک نود را مشخص میکند. در اینجا چون با کلیک بر روی هر نود، فرزند آن از سرور واکشی میشود و lazy loading برقرار است، بازگشت مقدار n_level دریافتی از کلاینت به علاوه یک، کافی است. اگر نیاز است تمام نودها باز شده نمایش داده شوند، این مورد را باید به صورت دستی محاسبه کرده و در مدل BlogComment پیش بینی کنید.
در نهایت آرایهای از خواص مدنظر به همراه 4 خاصیت ساختار درختی باید به ترتیب بازگشت داده شوند.
فعال سازی سمت کاربر treeGrid
برای فعال سازی سمت کاربر نمایش درختی اطلاعات، باید سه خاصیت ذیل تنظیم شوند:
تنظیم treeGrid: true سبب فعال سازی treeGrid میشود. توسط treeGridModel حالات Nested Set model و Adjacency model قابل تنظیم هستند و ExpandColumn نام ستونی را مشخص میکند که قرار است فرزندان آن نمایش داده شوند.
یک نکتهی تکمیلی
اگر میخواهید دقیقا به شکل زیر برسید:
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید
jqGrid13.zip
برای مطالعه بیشتر
Tree Grid
Nested Set Model
Adjacency Model
در اینجا روش Adjacency model را به علت بیشتر مرسوم بودن آن و شباهت بسیار زیاد آن به «مدلهای خود ارجاع دهنده» بررسی خواهیم کرد.
مدل دادهای Adjacency
در حالت ساختار درختی از نوع مجاورت، علاوه بر خواص اصلی یک کلاس، سه خاصیت دیگر نیز باید تعریف شوند:
using System; namespace jqGrid13.Models { public class BlogComment { // Other properties public int Id { set; get; } public string Body { set; get; } public DateTime AddDateTime { set; get; } // for treeGridModel: 'adjacency' public int? ParentId { get; set; } public bool IsNotExpandable { get; set; } public bool IsExpanded { get; set; } } }
IsNotExpandable به این معنا است که نود جاری آیا قرار است باز شود و فرزندی دارد یا خیر؟ اگر فرزندی ندارد باید مساوی True قرار گیرد.
IsExpanded حالت پیش فرض باز بودن یا نبودن یک نود را مشخص میکند.
نحوهی بازگشت اطلاعات درختی از سمت سرور
در نگارش فعلی jqGrid، در حالت نمایش درختی، مباحث صفحه بندی و مرتب سازی غیرفعال هستند و کدهای مرتبط با آن که در اینجا ذکر شدهاند، فعلا تاثیری ندارند (البته با کمی تغییر در کدهای آن، میتوان این قابلیت را هم فعال کرد. اطلاعات بیشتر).
نکتهی مهم treeGrid، سه پارامتر دیگر هستند که از سمت کلاینت به سرور ارسال میشوند:
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Web.Mvc; using jqGrid13.Models; using JqGridHelper.DynamicSearch; // for dynamic OrderBy using JqGridHelper.Models; using JqGridHelper.Utils; namespace jqGrid13.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult GetComments(JqGridRequest request, int? nodeid, int? parentid, int? n_level) { var list = BlogCommentsDataSource.LatestBlogComments; // در این حالت خاص فعلا در نگارش جای جیکیوگرید صفحه بندی کار نمیکند و فعال نیست و محاسبات ذیل اهمیتی ندارند var pageIndex = request.page - 1; var pageSize = request.rows; var totalRecords = list.Count; var totalPages = (int)Math.Ceiling(totalRecords / (float)pageSize); var productsQuery = list.AsQueryable(); if (nodeid == null) { productsQuery = productsQuery.Where(x => x.ParentId == null); } else { productsQuery = productsQuery.Where(x => x.ParentId == nodeid.Value); } var products = productsQuery.OrderBy(request.sidx + " " + request.sord) .Skip(pageIndex * pageSize) .Take(pageSize) .ToList(); var newLevel = n_level == null ? 0 : n_level.Value + 1; var productsData = new JqGridData { Total = totalPages, Page = request.page, Records = totalRecords, Rows = (products.Select(comment => new JqGridRowData { Id = comment.Id, RowCells = new List<object> { comment.Id, comment.Body, comment.AddDateTime.ToPersianDate(), // اطلاعات خاص نمایش درختی به ترتیب newLevel, comment.ParentId == null ? "" : comment.ParentId.Value.ToString(CultureInfo.InvariantCulture), comment.IsNotExpandable, comment.IsExpanded } })).ToList() }; return Json(productsData, JsonRequestBehavior.AllowGet); } } }
n_level مقدار جلو رفتگی نمایش اطلاعات یک نود را مشخص میکند. در اینجا چون با کلیک بر روی هر نود، فرزند آن از سرور واکشی میشود و lazy loading برقرار است، بازگشت مقدار n_level دریافتی از کلاینت به علاوه یک، کافی است. اگر نیاز است تمام نودها باز شده نمایش داده شوند، این مورد را باید به صورت دستی محاسبه کرده و در مدل BlogComment پیش بینی کنید.
در نهایت آرایهای از خواص مدنظر به همراه 4 خاصیت ساختار درختی باید به ترتیب بازگشت داده شوند.
فعال سازی سمت کاربر treeGrid
برای فعال سازی سمت کاربر نمایش درختی اطلاعات، باید سه خاصیت ذیل تنظیم شوند:
$('#list').jqGrid({ caption: "آزمایش سیزدهم", // .... مانند قبل treeGrid: true, treeGridModel: 'adjacency', ExpandColumn: '@(StronglyTyped.PropertyName<BlogComment>(x => x.Body))' }).jqGrid('gridResize', { minWidth: 400 }); });
یک نکتهی تکمیلی
اگر میخواهید دقیقا به شکل زیر برسید:
تنظیم rownumbers: true گرید را حذف کنید. همچنین ستون Id را نیز با تنظیمهای hidden:true, key: true مخفی نمائید (در تعاریف colModel).
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید
jqGrid13.zip
برای مطالعه بیشتر
Tree Grid
Nested Set Model
Adjacency Model