web-dev-qa-db-ja.com

コレクション内の各アイテムにDisplayTemplate(DisplayForを使用)を使用する

CommentクラスのDisplayTemplateを作成し、それをComment/DisplayTemplates/Comment.cshtml内に配置しました。

Comment.cshtmlは正しく入力されています:

@model Comment

次に、モデルのIEnumerable<Comment>を取得する部分ビューがあります。そこで、コレクションをループして、CommentクラスにDisplayTemplateを使用したいと思います。ビュー、その整合性:

@model IEnumerable<Comment>

@foreach (var comment in Model.Where(c => c.Parent == null)) { 
    @Html.DisplayFor(model => comment)
}

ただし、Html.DisplayFor行でエラーが発生します。

ディクショナリに渡されるモデルアイテムのタイプは「System.Int32」ですが、このディクショナリにはタイプ「System.String」のモデルアイテムが必要です。

foreachループ内の各アイテムに対してDisplayTemplateを呼び出すにはどうすればよいですか?

22
Sergi Papaseit

IEnumerable<Comment>を取り、コレクションをループして適切な表示テンプレートを呼び出すだけのビューを作成する代わりに、次のようにします。

@Html.DisplayFor(x => x.Comments)

ここで、CommentsプロパティはIEnumerable<Comment>であり、ループを自動的に実行し、このコレクションの各アイテムのComment.cshtml表示テンプレートをレンダリングします。

または、本当にそのようなビューが必要な場合(理由はわかりません)、次のようにすることができます。

@model IEnumerable<Comment>
@Html.DisplayForModel()

そこで使用しているWhere句に関しては、それを削除して、このタスクをコントローラーに委任する必要があります。このようなタスクを実行するビューではなく、ビューモデルを準備するのはコントローラーの責任です。

33
Darin Dimitrov

受け入れられた回答はほとんどの場合うまく機能しますが、レンダリング時に要素のインデックスを認識する必要がある場合もあります(つまり、インデックスに基づいて各要素への参照を生成するカスタムJavaScriptを追加します)。

その場合でも、DisplayForは次のようにループ内で使用できます。

@model IEnumerable<Comment>

@for (int index = 0; index < Model.Count(); index++)
{
     @Html.DisplayFor(model => model[index])
}
13
Fernando Neira