7

アプリケーションは、RAZOR ビュー エンジンを使用した MVC3 アプリケーションです。

ここで使用されているコントローラーは TestController です。ネストされたビューを使用しています。

Base view(Item Listing)はこんな感じで、

//Listing.cshtml
@model ItemsList 
@for (int i = 0; i < Model.Items.Count(); i++)
    {
        @Html.DisplayFor(x => x.Items[i], new { RowPosition = i})
}

アイテムのテンプレートはこちら

//Item.cshtml
@model Item
@Html.DisplayFor(x=>x.HeaderText)
@Html.DisplayFor(x=>x, "ItemDetails")

そして、ここにアイテムの詳細のビューがあります

//ItemDetails.cshtml
@model Item
@Html.DisplayFor(x=>x.Description)

そのため、モデルを ITEM テンプレートから ITEMDETAILS テンプレートに転送しようとしています。ItemDetails.cshtml は、"Views\Test\DisplayTemplates" の下に配置されます。実際、「Views\Shared」フォルダーと「Views\Shared\DisplayTemplates」フォルダーの下に配置しようとしました。しかし、Viewエンジンはそれを拾っていないようです。

ただし、Microsoft のドキュメントは、ビュー エンジンが Controller\DisplayTemplates フォルダーを調べて、使用されている TemplateName を使用して VIEW を取得すると述べています。

4

3 に答える 3

6

これは、Display/EditorTemplates の意図された動作であると思われます。おそらく、次のようなカスタム表示テンプレートでの偶発的な無限再帰を防ぐためです (in Item.cshtml):

@model Item
@Html.DisplayFor(x => x)

Item.cshtml...これは、 DisplayTemplateを無限に表示します。

明らかにあなたの例では、アイテム/モデルをのテンプレートに渡しているので、無限再帰は発生しません。ただし、フレームワーク内の同じセーフガードに引っかかるようです。それが「バグ」として分類されるのか、単に「設計による」ものとして分類されるのかよくわかりませんか?

これはDisplayFor/TemplateFor ヘルパーのチェックです:

// Normally this shouldn't happen, unless someone writes their own custom Object templates which 
// don't check to make sure that the object hasn't already been displayed 
object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) {    // DDB #224750 
    return String.Empty;
}

ViewData.TemplateInfo.VisitedObjects親テンプレートの訪問したオブジェクト/モデルを保存します。実行すると:

@Html.DisplayFor(x => x.Items[i], new { RowPosition = i})

Item.cshtmlDisplayTemplate をレンダリングし、アイテム/モデルを に追加しますVisitedObjects。これはItem.cshtml、同じアイテム/モデルを持つ別の子テンプレートを表示しようとした場合を意味します:

@Html.DisplayFor(x => x, "ItemDetails")

アイテム/モデルは既に にVisitedObjectsあるため、上記の if ステートメントは true を返し、レンダリングする代わりに、何もItemDetails.cshtml言わずに空の文字列を返す/レンダリングします。

于 2012-05-03T21:56:04.133 に答える
1

使ってみてください@Html.RenderPartial("ItemDetails", item)

于 2012-05-03T21:13:59.907 に答える
0

まず、for ループを使用しないでください。Display/EditorTemplates はコレクションを処理できます。

次に、ItemsList とは何ですか? そして、それはどのように定義されていますか?特定のコレクション タイプに名前を付けるだけの場合は、そうしないでください。代わりに List などを用意してください (特別な項目の処理が必要な場合を除きます。その場合は、コレクション クラスに IEnumerable を実装します)。List を使用するように変換すると、ItemsList.cshtml または単に Item.cshtml になります。

また、メイン ビューの DisplayFor() が間違っています。そのようにhtml属性をDisplayTemplatesに渡すことはできません。

于 2012-05-03T21:09:42.497 に答える