Этот пост является обновлением моего исходного ASP.NET MVC Recursive TreeView Helper почти 3 года назад. Как ни странно, это по-прежнему пост с высоким трафиком и около 50 комментариев, требующих обновления или полного решения для загрузки. Я подумал, что если я собираюсь сделать это, я мог бы также дать API крайне необходимый фейслифтинг и вставить его в NuGet.
Что это такое?
Учитывая следующую самореферентную иерархическую модель…
public class TreeViewLocation { public TreeViewLocation() { ChildLocations = new HashSet<TreeViewLocation>(); } public int Id { get; set; } public string Name { get; set; } public virtual int? ParentLocationId { get; set; } public virtual ICollection<TreeViewLocation> ChildLocations { get; set; } }
… Мы хотим создать неупорядоченный список HTML, как этот
как выглядит новый API?
Во-первых, извинения за смешивание подсветки синтаксиса. У моего по умолчанию еще нет отличной темы Razor.
Следующая Razor показывает API, который мы создадим. Он придерживается свободного синтаксиса, который многие разработчики предпочитают альтернативному (десятки перегрузок!). В конце концов, нам легче писать, легче расширять в будущем, и его легче обнаружить разработчикам, которые будут использовать его позже. Эта конкретная реализация TreeView также использует превосходный шаблонизатор HelperResult от Razor (синтаксис @ <text> показан ниже).
@model List<MvcTreeView.Models.Location> @(Html.TreeView(Model) .EmptyContent("No locations have been defined yet!") .Children(m => m.ChildLocations) .HtmlAttributes(new { id = "tree"}) .ChildrenHtmlAttributes(new { @class = "subItem"}) .ItemText(m => m.Name) .ItemTemplate( @<text> <a href="#@item.Id">@item.Name</a> </text>) )
Как это было написано?
Определение свободного API
Написание свободного API, как правило, довольно просто. Ключевое требование заключается в том, чтобы каждый метод возвращал тип класса и всегда заканчивался словами «вернуть это»; Остальная часть тела метода обычно просто сохраняет некоторое состояние в закрытом поле, которое в конечном итоге будет использоваться для визуализации настроенного пользовательского интерфейса.
Например, чтобы установить ItemText, который будет отображать метку элемента в каждом <li>, мы берем селектор свойств и просто сохраняем его в поле _displayProperty, в конечном итоге возвращая текущий экземпляр, позволяющий объединить дальнейшие методы.
public TreeView<T> ItemText(Func<T, string> selector) { if (selector == null) throw new ArgumentNullException("selector"); _displayProperty = selector; return this; }
Рендеринг / IHtmlString
Наконец, как только разработчик настроил, как именно должен отображаться TreeView, нам нужно вывести HTML.
Один из способов подключиться к этой инфраструктуре — реализовать как IHtmlString, так и переопределить ToString () . MVC проверит, реализуем ли мы IHtmlString и, если это так, вызовет ToHtmlString (), чтобы запустить рендеринг, который написан для просмотра.
Также обратите внимание на вызов ValidateSettings () — это необходимо во многих гибких конфигурациях, поскольку такие API-интерфейсы иногда допускают неверную конфигурацию. Например, используя 2 несовместимых метода, таких как ItemText () и ItemTemplate () вместе — обычно вы либо хотите использовать простое текстовое отображение или полноразмерное отображение шаблона — но невозможно использовать оба. Мы могли бы выбросить исключение, предупреждая разработчика о том, что это неверная конфигурация.
public override string ToString() { ValidateSettings(); var listItems = _items.ToList(); var ul = new TagBuilder("ul"); ul.MergeAttributes(_htmlAttributes); // snip... return ul.ToString(); } public string ToHtmlString() { return ToString(); }
Получить код
Этот помощник очень легко добавить в ваш проект с помощью NuGet. В качестве альтернативы вы все равно можете пойти по ручному маршруту и получить код из CodePlex.
NuGet / Образец пакета NuGet
В этот проект я решил включить образец пакета NuGet, который используется для простой демонстрации использования помощника.
Это пакеты только для исходного кода. Установив этот пакет в свой проект, вы получите необработанный файл в Helpers \ TreeView.cs, который вы можете редактировать или обновлять по своему усмотрению.
В примере проекта используется та же концепция, он добавляет TreeViewController и представление TreeView.cshtml, которое демонстрирует использование помощника TreeView. После того, как вы опробовали пример и поиграли с ним, очень легко удалить его через NuGet, чтобы удалить ненужные файлы.
CodePlex
И, конечно же, полный исходный код доступен для скачивания на CodePlex.