MVC 3複数のDisplayFor-Templates
-
27-10-2019 - |
質問
バスケットアイテムリストのカスタムテンプレートを作成しようとしています。アイテムがWebページにあるかメールにあるかに応じて、アイテムを表示するさまざまな方法があるため、いくつかの異なるテンプレートが必要です。私の問題は、デフォルト名を使用すると完璧に動作することです。
@Html.DisplayFor(b => b.Items)
しかし、テンプレート名を追加しようとすると、テンプレートがバスケット項目ではなくリストタイプのアイネラルである必要があるという予測が得られます。
@Html.DisplayFor(i => basket.Items, "CustomerItemBaseList")
私の間違いがあるアイデア、またはそれが不可能な理由は高く評価されています。ありがとう。
解決
残念ながら、それはテンプレートのヘルパーの制限です。コレクションプロパティのテンプレート名を指定した場合、テンプレートはコレクションの各アイテムに自動的に適用されなくなります。可能性のある回避策:
@for (int i = 0; i < Model.Items.Length; i++)
{
@Html.DisplayFor(x => x.Items[i], "CustomerItemBaseList")
}
他のヒント
それは良い考えです、ダリン。私は怠け者なので、さらに一歩進んで、これをラップする実際のヘルパーを作りたいと思います。また、私のケースのためにそれを簡素化するためにラムダの表現を取り出しましたが、その機能を簡単に追加することができます。
public static class DisplayTextListExtension
{
public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName)
{
var tempResult = new StringBuilder();
foreach (var item in model)
{
tempResult.Append(html.DisplayFor(m => item, templateName));
}
return MvcHtmlString.Create(tempResult.ToString());
}
}
その後、実際の使用法は次のようになります。
@Html.DisplayForList(Model.Organizations, "infoBtn")
私はダンの答えが好きでしたが、それがあらゆるもので機能する可能性があるので、少し調整しました:
using System.Collections;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace YourProject.Whatever
{
public static class DisplayExtensions
{
public static MvcHtmlString DisplayForIEnumerable<TModel>(this HtmlHelper<TModel> html, IEnumerable model, string templateName)
{
var tempResult = new StringBuilder();
foreach (var item in model)
{
var item1 = item;
tempResult.Append(html.DisplayFor(m => item1, templateName));
}
return MvcHtmlString.Create(tempResult.ToString());
}
}
}
そしてもちろん:
@Html.DisplayForIEnumerable(Model.Organizations, "NameOfYourDisplayTemplate")
不均一なオブジェクトのリスト(すなわち、バスケット項目サブクラス)を使用して、さらに便利な別のソリューションをお勧めします。 追加のviewdata のパラメーター DisplayFor
方法、次のようなもの:
@DisplayFor(b=>b.Items, new { layout="row" })
このようにして、ヘルパーは正常に動作します IEnumerable<T>
, 、各アイテム(tのサブクラス)を呼びます相対 displayTemplate, 、それを渡します 追加のviewdata の値 ViewData
辞書。
テンプレートは、異なるレイアウト値に対して異なるコードを出力することができます。
上の例では、view shared displaytemplates という名前のテンプレートBasketItem (またはサブクラスの名前)は次のようなものでなければなりません。
@model MyProject.BasketItem // or BasketItem subclass
@{
string layout = ViewData["layout"] as string ?? "default";
switch(layout)
{
case "row":
<div class="row">
...
</div>
break;
// other layouts
...
default: // strongly recommended a default case
<div class="default-view>
...
</div>
break;
}
}
常にデフォルトのコードを提供することを強くお勧めします。
この提案が役立つことを願っています。