8

Tôi có một khung nhìn một phần trong một dự án MVC 4, được gõ mạnh mẽ. Phải mất một bộ sưu tập IEnumerable của một bảng cơ sở dữ liệu. Trong bảng đó có các ID, Tên và ParentID để lưu trữ kết nối phân cấp giữa các bản ghi. Quan điểm cho rằng gọi là xem một phần cũng là mạnh mẽ đánh máy, phải mất toàn bộ cơ sở dữ liệu như mô hình, và vượt qua bảng Categories đến xem một phần, như một bộ sưu tập đếm được:ASP.NET MVC 4 tạo ra một khung nhìn tre với một phần xem đệ quy

@Html.Partial("_TreeCategories", @Model.Categories.ToList()) 

Và trong giao diện một phần, tôi muốn lấy các nút gốc đầu tiên, vì vậy tôi có thể mở rộng toàn bộ cây theo cách đệ quy. Trong bảng cơ sở dữ liệu, tất cả các bản ghi được coi là các nút gốc với một ParentID == null.
Vì vậy, nhìn chung, cách của tôi để làm điều này sẽ như thế nào:

@model IEnumerable<TreeCollections.OpenAccess.Category> 

@if (Model.ToList().Count >= 0) 
    { 
    @if (Model.ToList()[0].Parent_id == null) 
    { 
     <text><ul id="navigation"></text> 
    } 

    @foreach (var node in @Model) 
    { 
     <li><a href="[email protected]">@node.Name</a> 
      @foreach (var subNode in @Model.Where(s => s.Parent_id == node.Id)) 
      { 
       @Html.Partial("_TreeCategories", subNode) 
      } 
     </li> 
    } 
    @if (Model.ToList()[0].Parent_id == null) 
    { 
     </ul> 
    } 
} 

Vì vậy, tôi kiểm tra xem ParentID phần tử đầu tiên của mô hình là null, và nếu nó là, sau đó nó nên tạo một < ul> tag với id "điều hướng", do đó, plugin jquery có thể nhận ra rằng nó có nghĩa là để được một kiểm soát treeview. Sau đó, nó tạo ra một thẻ danh sách với một cuộc gọi đệ quy bên trong. Chế độ xem từng phần được gọi là đệ quy lấy các nút con của nút làm mô hình. Và cuối cùng, nếu chúng tôi đến cuối phần hiển thị của chế độ xem một phần và chúng tôi đang ở cấp "root", bạn nên viết một thẻ đóng < ul>
Tuy nhiên, có một số vấn đề. Đầu tiên, cuối cùng, việc đóng thẻ danh sách không theo thứ tự là sai, VS không thể tìm thấy thẻ bắt đầu phù hợp cho điều đó. Thứ hai, tôi không biết tại sao, nhưng ở trên cùng, tôi có thể đặt thẻ starter < ul> vào giữa các thẻ và tôi không thể thực hiện điều đó ở thẻ đóng bên dưới. Nhưng tôi cũng không chắc chắn về những thẻ này, tôi cảm thấy chúng cũng sai.

Xin vui lòng, giúp tôi, tôi bị mắc kẹt với điều này trong nhiều ngày nay.

Trả lời

15

người đàn ông, bạn có một số chiến thắng đang diễn ra tại đây. tôi cảm thấy nỗi đau của bạn bị kẹt.

xem nếu điều này nổi thuyền của bạn.

bạn cần giá trị hạt giống để theo dõi những gì bạn đang tìm kiếm trong danh sách khi bạn đệ quy trên cùng một danh sách. tốt hơn là nên làm một đứa trẻ cha mẹ lập bản đồ trong lớp, nhưng meh điều này thật thú vị khi làm cho cấu trúc của bạn và nên làm điều đó.

Models

namespace trash.Models 
{ 
    public class Category 
    { 
     public int ID { get; set; } 
     public int? Parent_ID { get; set; } 
     public string Name {get; set;} 
    } 

    public class SeededCategories 
    { 
     public int? Seed { get; set; } 
     public IList<Category> Categories { get; set; } 
    } 
} 

Controller (Chú ý: bạn khởi động dây chuyền đệ quy bằng cách thiết lập thuộc tính Seed null sẽ nhận tất cả các bậc phụ huynh vô)

namespace trash.Controllers 
{ 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      IList<trash.Models.Category> categories = new List<trash.Models.Category>(); 
      categories.Add(new trash.Models.Category { ID = 1, Parent_ID = null, Name = "Top1" }); 
      categories.Add(new trash.Models.Category { ID = 2, Parent_ID = null, Name = "Top2" }); 
      categories.Add(new trash.Models.Category { ID = 3, Parent_ID = 1, Name = "Top1Ring1" }); 
      categories.Add(new trash.Models.Category { ID = 4, Parent_ID = 1, Name = "Top1Ring2" }); 

      trash.Models.SeededCategories model = new Models.SeededCategories { Seed = null, Categories = categories }; 
      return View(model); 
     } 
    } 
} 

Lần Index

@model trash.Models.SeededCategories 

Here's a list 
@Html.Partial("_TreeCategories", Model) 

một phần (_TreeCategories của bạn. LƯU Ý: đặt Seed thành ID nút hiện tại và số lần truy cập volia)

@model trash.Models.SeededCategories 

@if (Model.Categories.Where(s => s.Parent_ID == Model.Seed).Any()) 
{ 
    <ul> 
     @foreach (var node in Model.Categories) 
     { 
      if (node.Parent_ID == Model.Seed) 
      { 
       trash.Models.SeededCategories inner = new trash.Models.SeededCategories { Seed = node.ID, Categories = Model.Categories }; 
      <li><a href="[email protected]">@node.Name</a> 
       @Html.Partial("_TreeCategories", inner) 
      </li> 
      } 
     } 
    </ul> 
} 
+0

Cảm ơn bạn, nó rất rõ ràng, tuy nhiên, tôi đã nhầm lẫn về nó trong nhiều ngày ... Tôi vừa cài đặt lại toàn bộ hệ thống trên máy tính, phải mất một thời gian cho đến khi tôi tải xuống và cài đặt lại Visual Studio ra, nhưng ít nhất tôi nhìn thấy mô hình bây giờ! Cảm ơn bạn rất nhiều! – user2082422

+0

đó là cách hầu hết thời gian, vui lòng giúp đỡ –

+0

Nhân tiện, bạn nên giới thiệu loại ánh xạ bố mẹ-con nào? Tôi đã chọn phương thức "ID - ParentID" vì đây là một cách để thực hiện cấu trúc dữ liệu phân cấp trong một datamodel quan hệ, chẳng hạn như một cơ sở dữ liệu. Trong ID bảng danh mục là khóa chính, ParentID là khóa ngoài tham chiếu đến Categories.ID. – user2082422

1

Bạn có thể thử đệ quy của giao diện người dùng Shield TreeView for ASP.NET MVC.

Nó cho phép bạn chỉ định tất cả các mục TreeView sử dụng đối tượng RecursiveDataSource, có thể được thiết lập để truy xuất dữ liệu cho mục cây từ điểm cuối từ xa hoặc nguồn cục bộ "lazily", bất cứ khi nào mục đang được mở rộng.RecursiveDataSource là một trình bao bọc xung quanh một tiện ích JavaScript DS, giới thiệu nhu cầu về một số mã JS, cũng như cập nhật mã máy chủ của bạn sẽ cung cấp dữ liệu (hoặc triển khai dịch vụ web hoặc đặt dữ liệu trong JS) biến trong chế độ xem của bạn).

+0

Liên kết tới giải pháp tiềm năng luôn được chào đón, nhưng vui lòng [thêm ngữ cảnh xung quanh liên kết] (// meta.stackoverflow.com/a/8259) để người dùng đồng nghiệp của bạn sẽ biết ý tưởng đó là gì và tại sao lại có nó. Luôn trích dẫn phần có liên quan nhất của một liên kết quan trọng, trong trường hợp trang web mục tiêu không thể truy cập được hoặc sẽ vĩnh viễn ngoại tuyến. Có tính đến _barely nhiều hơn một liên kết đến một trang web bên ngoài_ là một lý do có thể là [Tại sao và làm thế nào là một số câu trả lời bị xóa?] (// stackoverflow.com/help/deleted-answers). – FrankerZ

+0

Đã cập nhật câu trả lời –

Các vấn đề liên quan