Этот пост является обновлением моего исходного 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.


