機能:
- リスト表示
- アイテムを追加する
- アイテムの移動
- アイテムを削除する
使用されるテクノロジー:
- Microsoft ASP NET MVC 4
- エンティティフレームワーク
- エンティティへのLinq
- Microsoft SQL Server(ローカルDB)
データベース
すべてのレコードはデータベースに保存されるため、次のテーブルを作成する必要があります。
public class News { public int Id {get;set;} // public int? ParentId {get;set;} // public string Title {get;set;} // public bool IsDeleted {get;set;} // }
モデル
次に、作業用のモデルを作成します。
1.通常、モデルはデータベースレコードを直接使用しないため、テーブルに似たモデルを作成します。
public class NewsModel { public int Id {get;set;} // public int? ParentId {get;set;} // public string Title {get;set;} // }
2.ニュースのリスト。
public NewsListModel { public int? Seed {get;set;} // public IEnumerable<NewsModel> News {get;set;} // }
コントローラー
以下は、ニュースを選択、削除、追加、移動できるコントローラーです。
public class NewsController : Controller { public ActionResult Index() { using (NewsContext context = new NewsContext()) { NewsListModel model = new NewsListModel() { News = context.News.Where(x => !x.IsDeleted).ToArray().Select(x => new NewsModel(x)) }; return View(model); } } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Add(int? parentId, string title) { using (NewsContext context = new NewsContext()) { var newNews = new News() { ParentId = parentId, Title = title }; context.News.Add(newNews); context.SaveChanges(); } return RedirectToAction("Index"); } [ValidateAntiForgeryToken] [HttpPost] public ActionResult Move(int nodeId, int? newParentId) { if (nodeId == newParentId) { return RedirectToAction("Index"); } using (NewsContext context = new NewsContext()) { if (newParentId.HasValue && ContainsChilds(context, nodeId, newParentId.Value)) { return RedirectToAction("Index"); } var node = context.News.Where(x => x.Id == nodeId).Single(); node.ParentId = newParentId; context.SaveChanges(); } return RedirectToAction("Index"); } private bool ContainsChilds(NewsContext context, int parentId, int id) { bool result = false; var inner = context.News.Where(x => x.ParentId == parentId && !x.IsDeleted).ToArray(); foreach (var node in inner) { if (node.Id == id && node.ParentId == parentId) { return true; } result = ContainsChilds(context, node.Id, id); } return result; } [HttpPost] public ActionResult Delete(int id) { using (NewsContext context = new NewsContext()) { DeleteNodes(context, id); context.SaveChanges(); } return RedirectToAction("Index"); } private void DeleteNodes(NewsContext context, int id) { var inner = context.News.Where(x => x.ParentId == id && !x.IsDeleted).ToArray(); foreach (var node in inner) { node.IsDeleted = true; DeleteNodes(context, node.Id); } var deleted = context.News.Where(x => x.Id == id && !x.IsDeleted).Single(); deleted.IsDeleted = true; } }
提出
コードからわかるように、ほとんどのメソッドは再帰的に実行されます。 再帰により、操作を簡潔に実装できます。 再帰は、ページに表示するときにも使用されます。 ツリービューの出力を検討してください。
_TreeList.cshtml
@model MySLOTree.Models.NewsListModel @if (Model.News.Where(x => x.ParentId == Model.Seed).Any()) { <ul> @foreach (var node in Model.News) { if (node.ParentId == Model.Seed) { <a>@node.Title</a> MySLOTree.Models.NewsListModel inner = new MySLOTree.Models.NewsListModel { Seed = node.Id, News = Model.News }; @Html.Partial("_TreeList", inner) } } </ul> }
結果
空のリスト
アイテムを追加する
リスト表示
リストを折りたたむ/展開する
アイテムの移動
おわりに
ツリー内のアイテムを移動するには、ドラッグアンドドロップを使用します。 要素を追加および削除するには、対応するアイコンをクリックします。 記事はいくつかの点を省略しました。 詳細はすべてソースコードで確認できます。
完全なソースコードはgithubで入手できます。
PS質問に答えたり、経験を交換したりできます。