Добрый день! На хабре есть статья, в которой рассказывается как сделать древовидный список. Однако, в этой версии будет использован движок Razor, Entity Framework и др., а так же реализованы операции со списком. Данный вариант отличается простотой и быстротой реализации. Статья рассчитана на тех, кто уже знаком с ASP .NET MVC.
Используемые технологии:
Так как все записи будут храниться в базе данных, то необходимо создать следующую таблицу:
Далее создадим модели для работы:
1. Обычно в моделях не используют напрямую записи из базы данных, поэтому создадим модель похожую на таблицу.
2. Список новостей.
Ниже представлен контроллер, который умеет выбирать, удалять, добавлять и перемещать новости.
Как видно из кода, большинство методов выполняются рекурсивно. Рекурсия позволяет достаточно лаконично реализовать операции. Так же рекурсия используется при отображении на странице. Рассмотрим вывод древовидного списка.
Для перемещения элементов в дереве используется drag and drop. Добавление и удаление элементов происходит путем нажатия соответствующих иконок. В статье опущены некоторые моменты. Все подробности можно увидеть в исходном коде.
Полный исходный код доступен на github.
Возможности:
- Отображение списка
- Добавление элементов
- Перемещение элементов
- Удаление элементов
Используемые технологии:
- Microsoft ASP. NET MVC 4
- Entity Framework
- Linq to Entity
- Microsoft SQL Server (Local 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>
}
Результат
Пустой список
Добавление элементов
Отображение списка
Сворачивание\Разворачивание списка
Перемещение элементов
Заключение
Для перемещения элементов в дереве используется drag and drop. Добавление и удаление элементов происходит путем нажатия соответствующих иконок. В статье опущены некоторые моменты. Все подробности можно увидеть в исходном коде.
Полный исходный код доступен на github.
P.S. С радостью отвечу на вопросы и обменяюсь опытом.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.
Комментариев нет:
Отправить комментарий