web-dev-qa-db-ja.com

ASP.NET MVC 4は、再帰的な部分ビューを使用してツリービューを生成します

強く型付けされたMVC4プロジェクトの部分的なビューがあります。データベースのテーブルのIEnumerableコレクションを取ります。そのテーブルには、レコード間の階層接続を格納するためのID、名前、およびParentIDがあります。部分ビューを呼び出すビューも強く型付けされており、データベース全体をモデルとして受け取り、Categoriesテーブルを列挙可能なコレクションとして部分ビューに渡します。

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

そして、部分ビューでは、最初にルートノードを取得したいので、ツリー全体を再帰的に拡張できます。データベーステーブルでは、すべてのレコードは、ParentID == nullのルートノードと見なされます。
したがって、一般的に、これを行う私の方法は次のようになります。

@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>
    }
}

したがって、モデルの最初の要素のParentIDがnullであるかどうかを確認し、nullである場合は、IDが「navigation」の<ul>タグを作成する必要があります。これにより、jqueryプラグインはそれがツリービューコントロールであることを認識できます。 。次に、再帰呼び出しを含むリストタグを作成します。再帰的に呼び出される部分ビューは、ノードの子をモデルとして取ります。そして最後に、部分ビューのレンダリングの最後に到達し、「ルートレベル」にいる場合は、終了<ul>タグを書き込む必要があります。
ただし、いくつかの問題があります。まず、最後に、順序付けされていないリストタグを閉じるのが間違っているため、VSはそれに一致する開始タグを見つけることができません。次に、理由はわかりませんが、上部のタグの間にスターター<ul>タグを配置できますが、下の終了タグでは配置できません。しかし、これらの<ul>タグについてもよくわかりません。また、それらも間違っていると感じています。

助けてください、私はこれで何日も立ち往生しています。

9
user2082422

男、あなたはここで起こっているいくつかの奇抜さを得ました。立ち往生してあなたの痛みを感じます。

これがあなたのボートを浮かせるかどうか見てください。

同じリストで再帰を実行するときに、リストで探しているものを追跡するためのシード値が必要です。クラスで親子のマッピングを行う方が良いですが、構造を考えるとこれは面白かったので、トリックを実行する必要があります。

モデル

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; }
    }
}

コントローラ(注:Seedプロパティをnullに設定すると、再帰チェーンが開始され、すべてのnull親が取得されます)

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);
        }
    }
}

ビューインデックス

@model trash.Models.SeededCategories

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

部分的(_TreeCategories。注:Seedを現在のノードIDと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>
}
16
hubson bropa

Shield UIの再帰を試すことができます TreeView for ASP.NET MVC

RecursiveDataSourceオブジェクトを使用してすべてのTreeViewアイテムを指定できます。このオブジェクトは、アイテムが展開されるたびに、リモートエンドポイントまたはローカルソースからツリーアイテムのデータを「遅延」で取得するように設定できます。

RecursiveDataSourceは、JavaScript DSウィジェットのラッパーであり、JSコードの必要性を導入し、データを提供するサーバーコードを更新します(Webサービスの実装または場所のいずれか)ビュー内のJS変数のデータ)。

1