ここで何が欠けていますか?
何もない。残念ながら、それはそうです。Html.EditorForを呼び出すとき、またはUIHintを使用するときにテンプレート名を指定すると、テンプレートは各要素ではなくリストに対して呼び出されます。
もちろん、この機能を実現するカスタム拡張メソッドを作成することもできます。
public static class HtmlExtensions
{
private class ViewDataContainer: IViewDataContainer
{
public ViewDataContainer(ViewDataDictionary viewData)
{
ViewData = viewData;
}
public ViewDataDictionary ViewData { get; set; }
}
public static IHtmlString EditorForCollection<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, IList<TProperty>>> expression
)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
if (string.IsNullOrEmpty(metadata.TemplateHint))
{
return html.EditorFor(expression);
}
var collection = metadata.Model as IList<TProperty>;
var sb = new StringBuilder();
for (int i = 0; i < collection.Count; i++)
{
var indexExpression = Expression.Constant(i, typeof(int));
var itemGetter = expression.Body.Type.GetProperty("Item", new[] { typeof(int) }).GetGetMethod();
var methodCallExpression = Expression.Call(expression.Body, itemGetter, indexExpression);
var itemExpression = Expression.Lambda<Func<TModel, TProperty>>(methodCallExpression, expression.Parameters[0]);
var result = html.EditorFor(itemExpression, metadata.TemplateHint).ToHtmlString();
sb.AppendLine(result);
}
return new HtmlString(sb.ToString());
}
}
UIHint属性で装飾されたタイプコレクションのビューモデルプロパティを操作できます。
public class MyViewModel
{
[UIHint("SomeTypeTemplate")]
public IList<ItemViewModel> Items { get; set; }
}
そしてあなたの見解では:
@model MyViewModel
@Html.EditorForCollection(x => x.Items)
そして、あなた~/Views/Shared/EditorTemplates/SomeTypeTemplate.cshtml
は今、単一にタイプすることができますItemViewModel
:
@model ItemViewModel
...
実際のテンプレートをループして呼び出すだけの中間表示テンプレートはもう必要ありません。これは本当に無駄です。