Способ инкапсулировать разделы многократного просмотра (т.е. Плитки, портлеты) с произвольным контентом?

Я все еще мочу с MVC и работаю на сайте, который использует много "плиток" (вы знаете, обычный "прямоугольный раздел со стандартным заголовком и некоторым контентом" ) для визуального отображения. Ничего необычного, просто способ разместить контент в коробки для удобства компоновки и навигации. В настоящее время "плитки" (мой термин) построены следующим образом:

<div>
 <div>
 <h2>Title</h2>
 </div>
 <div>
 (arbitrary content)
 </div>
</div>

Примечание: "произвольный контент" означает любой контент, статический или динамический, поэтому не обязательно что-то, что я могу подключить к переменной и передать в помощник, мне нужно немного больше гибкости.

Мой вопрос: какой оптимальный метод использовать для инкапсуляции этого шаблона и облегчения/выразительности вызова из кода? Я знаю о частичных представлениях, но как передать часть тела в частичное представление? (Это может быть просто ограниченное знание MVC)

Я попытался создать помощников Razor следующим образом:

@Tile.Begin("Title")
 (arbitrary content)
@Tile.End()

Но Razor задыхается, потому что я не могу включить закрывающий div "tile-body". (Если я это сделаю, тогда я должен передать содержимое тела в виде строковой переменной, и это не всегда возможно)

Я мог видеть что-то вроде этого:

@using (Tile.Begin("Title")) {
 (arbitrary content)
}

Это кажется мне самым элегантным, хотя и не так легко сканировать, как вызовы @Tile.Begin() и @Tile.End(). Из того, что я понимаю, мне нужно было бы создать класс и реализовать IDisposable, но когда я попытался возвратить строку сырых тегов HTML из вспомогательного класса, он просто написал синтаксис кодированного тега на экран, поэтому я предполагаю, что я столкнулся с здесь проблема?

Спасибо за любой совет.:)

1 ответ

Ну, я бы предложил использовать Display/EditorTemplates для создания динамической черепицы. Вы даже можете комбинировать их с html-помощником (не помощником бритвы).

Ваша проблема с пользовательским помощником html заключалась в том, что вы не делали это правильно. Вы должны использовать объект HtmlHelper. Правильный способ выглядит примерно так:

public static class TileExtension {
 public static TileHelper Tile(this HtmlHelper helper, string title) {
 helper.ViewContext.Writer.Write(
 "<div tile\""=""><div tile-header\""=""><h2>" + title + "</h2></div>"
 + "<div tile-body\""="">"
 );
 return new TileHelper(helper);
 }
 private class TileHelper : IDisposable {
 private HtmlHelper _helper;
 public TileHelper(HtmlHelper helper) { _helper = helper; }
 public void Dispose() {
 _helper.ViewContext.Writer.Write("</div></div>");
 }
 }
}

Тогда вы использовали бы это как @using(Html.Tile("Title")) { // your content }

Убедитесь, что вы уделяете пристальное внимание статическим ключевым словам и использованию ключевого слова this в параметре. Они необходимы, чтобы сделать работу с расширением.

Кроме того, вы должны добавить пространство имен, созданное вами этим классом, в элемент pages/namespaces web.config:

<pages>
 <namespaces>
 <add namespace="My.Name.Space">
 </add></namespaces>
</pages>

licensed under cc by-sa 3.0 with attribution.