ASP.NET MVC 4 RAZORデータベースからの動的なマルチレベルメニュー

前のDropDownListの投稿約束したように、MVC 4のデフォルトオプションに「値」を設定します 。今日は、MsSQLデータベースに格納された、無限のネストを持つ動的なマルチレベルメニューの構築について説明します。 かつてPCPでこれが数日間のタスクだったことを覚えています。 しかし、RAZORエンジンを搭載したMVC 4については、ほとんど理解できませんでしたが、結局のところ、いつものように、複雑なものや超自然的なものは何もありませんでした。 この記事は、方法がわからない人を対象としています。 より良い方法を知っているなら、それを共有してください。 始めましょう。

このマニュアルは、ASP.NET MVCアプリケーションのEntity Frameworkの記事を読んで得られた知識を既に活用していることを前提としています 。 またはこれら: ASP.NET MVC 4チュートリアル

1)最初に、データベースの構造を理解する必要があります。 これが主なものです。 この理論は、記事「 リレーショナルデータベースの階層データ構造」に記載されています 。 「祖先を参照する構造」と呼ばれる、可能な限り単純な構造を使用します。

SQLコードは次のようになります。
CREATE TABLE "CATALOG" ( "ID" INTEGER NOT NULL PRIMARY KEY, "NAME" VARCHAR(200) CHARACTER SET WIN1251 NOT NULL, "PARENT_ID" INTEGER ); 


VS 2012でモデルを作成します。
 using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace zf2.Models { public class NewsM { public int NewsMID { get; set; } public int ParentID { get; set; } public string Title { get; set; } public string AddTitle { get; set; } public string Description { get; set; } public string Content { get; set; } public DateTime ModDate { get; set; } } } 

一般に、最初の3つのフィールドのみが基本です。 しかし、明確にするために、私は自分のサイトで使用されている作業バージョンをもたらしました。

2)コントローラー。
  public ActionResult NewsA(int id = 1) //id     { ViewBag.Menu = db.NewsMs.ToList(); // ,     . ViewBag.Id = id; return View(); } 


3)部分ビュー
まだそれらに遭遇していない場合-それは大丈夫です。 通常のスクリプトとは、自動的に呼び出されないという点でのみ異なります。 これはいわばビューのビューです。

ビュー-共有-右クリック-追加-ビューのフォルダーに移動します:「部分ビューとして作成」にチェックマークを付けます。 名前「_Menu」を入力します。 なぜアンダースコアが使用されるのですか? はい、便宜上、名前の一致をなくすためです。 部分的なスクリプトは、Sharedタイプのすべてのディレクトリと、さまざまな拡張子を持つ対応するコントローラーで検索されるためです。 間違ったスクリプト名を設定した場合の結果は次のとおりです。
      "_gMenu"         .     : ~/Views/Home/_gMenu.aspx ~/Views/Home/_gMenu.ascx ~/Views/Shared/_gMenu.aspx ~/Views/Shared/_gMenu.ascx ~/Views/Home/_gMenu.cshtml ~/Views/Home/_gMenu.vbhtml ~/Views/Shared/_gMenu.cshtml ~/Views/Shared/_gMenu.vbhtml 

明らかだと思います
どうぞ
「_Menu.cshtml」で、次のコードをコピーします。
 @{ List<zf2.Models.NewsM> menuList = ViewBag.Menu; } <ul class="menu"> @foreach (var mp in menuList.Where(p => p.ParentID == 0)){ <li> @Html.ActionLink(mp.Title, ViewContext.RouteData.GetRequiredString("action"), new { id=mp.NewsMID }) @if( menuList.Count(p=>p.ParentID == mp.NewsMID ) > 0){ @:<ul> } @RenderMenuItem(menuList,mp) @if( menuList.Count(p=>p.ParentID == mp.NewsMID ) > 0){ @:</ul> } </li> } </ul> @helper RenderMenuItem(List<zf2.Models.NewsM> menuList, zf2.Models.NewsM mi) { foreach (var cp in menuList.Where(p => p.ParentID == mi.NewsMID)) { @:<li> @Html.ActionLink(cp.Title, ViewContext.RouteData.GetRequiredString("action"), new { id=cp.NewsMID }) if(menuList.Count(p=>p.ParentID == cp.NewsMID) > 0) { @:<ul> } @RenderMenuItem(menuList,cp) if(menuList.Count(p=>p.ParentID == cp.NewsMID) > 0) { @:</ul> } else { @:</li> } } } 

ここにすべての魔法があります。

@foreach (var mp in menuList.Where(p => p.ParentID == 0)) -ParentID = 0の名前を解析して表示します。

@RenderMenuItem(menuList,mp) -ビューヘルパーを呼び出します。これは、各「ルート」アイテムのすべてのネストをすでに再帰的に完了します。

@helper RenderMenuItem(List<zf2.Models.NewsM> menuList, zf2.Models.NewsM mi) -これはビューヘルパー自体であり、内部で再帰が構成されています。

@Html.ActionLink(mp.Title, ViewContext.RouteData.GetRequiredString("action"), new { id=mp.NewsMID }) -リンクを作成します。 標準ルーティングを使用していますが、コントローラー名は自動的に置き換えられます。 アクション名とパラメーターID-「手動で」を指定します。
ViewContext.RouteData.GetRequiredString("action") - ViewContext.RouteData.GetRequiredString("action")の名前を取得します。 同様に、コントローラーの名前を取得できます。
new { id=mp.NewsMID } -Idパラメーターを設定します。
mp.Titleリンク名

次に、「_ Content」という別の部分ビュースクリプトを作成します。
選択した記事の内容を送信されたIDに表示します。
コードは次のとおりです。
 @{ List<zf2.Models.NewsM> menuList = ViewBag.Menu; } @ViewBag.Id @foreach (var mp in menuList.Where(p => p.NewsMID == ViewBag.Id)) { @mp.Content @mp.AddTitle @mp.Description } 


4)メインビュースクリプト。 コントローラのアクション名のように呼び出されます-NewsA.cshtml
その中で、部分表示スクリプトを呼び出してヘッダーを表示するだけです。
 @{ ViewBag.Title = "NewsA"; } @{ List<zf2.Models.NewsM> menuList = ViewBag.Menu; } <div class="row"> <div class="span3"style="background-color: #e6e6e6;"> @Html.Partial("_Menu") </div> <div class="span6" style="background-color: #e6e6e6;"> @Html.Partial("_Content") </div> </div> 


, - Bootstrap - CSS . :

. . :
画像

:
.

Entity Framework
.
, .
:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using zf2.Models; namespace zf2.DAL { public class ZfInitializer : DropCreateDatabaseIfModelChanges<ZfContext> { protected override void Seed(ZfContext context) { var newsMs = new List<NewsM> { new NewsM { NewsMID = 1, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 2, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 3, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 4, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 5, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 6, ParentID = 3, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 7, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, }; newsMs.ForEach(s => context.NewsMs.Add(s)); context.SaveChanges(); } } }


...
  , -   Bootstrap -   CSS .     : 

. . :
画像

:
.

Entity Framework
.
, .
:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using zf2.Models; namespace zf2.DAL { public class ZfInitializer : DropCreateDatabaseIfModelChanges<ZfContext> { protected override void Seed(ZfContext context) { var newsMs = new List<NewsM> { new NewsM { NewsMID = 1, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 2, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 3, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 4, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 5, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 6, ParentID = 3, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 7, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, }; newsMs.ForEach(s => context.NewsMs.Add(s)); context.SaveChanges(); } } }


...
, - Bootstrap - CSS . :

. . :
画像

:
.

Entity Framework
.
, .
:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using zf2.Models; namespace zf2.DAL { public class ZfInitializer : DropCreateDatabaseIfModelChanges<ZfContext> { protected override void Seed(ZfContext context) { var newsMs = new List<NewsM> { new NewsM { NewsMID = 1, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 2, ParentID = 0, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 3, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 4, ParentID = 1, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 5, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 6, ParentID = 3, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, new NewsM { NewsMID = 7, ParentID = 2, Title = "Carson", AddTitle = "Carson", Description = "Carson", Content = "Carson" , ModDate = DateTime.Parse("2005-09-01") }, }; newsMs.ForEach(s => context.NewsMs.Add(s)); context.SaveChanges(); } } }


...

Source: https://habr.com/ru/post/J174531/


All Articles