4

適切なビューテンプレートを使用してアイテムを描画するための標準のMVCの例は次のとおりです。

Html.DisplayFor(m => m.Date)

ModelオブジェクトにDateTime型のDateという名前のプロパティがある場合、これはDisplay/DateTime.ascxテンプレートからHTMLを含む文字列を返します。

同じことをしたいが、強く型付けされたバージョンを使用できなかったとします。コンパイル時に、このビューのモデルの型がわかりませんでした。古いものを使用します:

Html.Display( "日付");

だからここに難しい部分があります。

モデルがIEnumerableであると仮定します。これらのオブジェクトがコンパイル時に何であるかはわかりませんが、実行時には、次のように、DateがDateTime型のオブジェクトになります。

public class ModelClass
{
    public DateTime Date { get; set; }
}

ここで、ビューでこれらのオブジェクトを反復処理し、それぞれをレンダリングするとします。あなたが気にかけているのがあなたがこれをすることができる価値だけであるならば:

<%
StringBuilder sb = new StringBuilder();
foreach(object obj in (IEnumerable<object>)Model)
{
    Type type = obj.GetType();

    foreach(PropertyInfo prop in type.GetProperties())
    {
        // TODO: Draw the appropriate Display PartialView/Template instead
        sb.AppendLine(prop.GetValue(obj, null).ToString());
    }
}
%>
<%= sb.ToString() %>

私は明らかに、この例に焦点を合わせ続けるためにいくつかの近道を取っています。

ここにポイントがあります-自分で書いたTODOをどのように実行しますか?値を取得したいだけではありません。Html.Display( "Date")のように適切にフォーマットしたいのです。しかし、Html.Display( "Date")を呼び出すだけで、IEnumerableであるModelを調べて、もちろん持っていないDateという名前のプロパティを探します。Html.Displayは、モデルとして使用する引数としてオブジェクトを取りません(Html.Display(obj、 "Date"など)。その下にあるすべてのクラスとメソッドは内部にあるように見えるので、'微調整して直接呼び出します。

私がやろうとしていることを達成するための簡単な方法があるはずですが、それを見つけることができないようです。

明確にするために、DateTime.ascxのコードの例を次に示します。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime>" %>
<%= Model.ToString("MM/dd/yyyy") %>

したがって、理想的には、任意のモデルを取得できるこのビューからの出力ですが、この場合、上記のこれらのModelClassオブジェクトの3つのリストは次のようになります。

2001年11月10日2002年11月10日2003年11月10日

コードはDateTimeのDisplayPartialViewを見つけて、それぞれに適切にレンダリングするためです。

では、どうすればTODOを実行できますか?

4

2 に答える 2

8

PhilHaackによるこのすばらしい投稿のテンプレートコードをご覧ください。それはあなたが探しているものに近づいているようです:http://haacked.com/archive/2010/05/05/asp-net-mvc-tabular-display-template.aspx

于 2010-10-20T11:33:12.287 に答える
0

私はこれに対する1つの潜在的な解決策を見つけましたが、私はそれが好きではありません。複数のファイルベースのテンプレートを使用する必要があります。つまり、複数のプロジェクトで使用するために、これをコードライブラリに簡単に抽象化することはできません。

景色:

<%
StringBuilder sb = new StringBuilder();

Type itemType = Model.GetType().GetGenericArguments()[0];

sb.AppendLine("<table>");

// Pass in the Model (IEnumerable<object>)'s generic item type as
// the Model for a PartialView that draws the header
sb.Append(Html.Partial("DisplayTableHead", itemType));

foreach(object item in (IEnumerable<object>)Model)
{
    sb.Append(Html.Partial("DisplayTableRow", item));
}

sb.AppendLine("</table>");
%>
<%= sb.ToString() %>

Views / Shared / DisplayTableHead.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Type>" %>
<tr>
<%
foreach (PropertyInfo prop in Model.GetProperties())
{
%>
<th><%= prop.Name %></th>
<%
}
%>
</tr>

Views / Shared / DisplayTableRow.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<tr>
<%
Type modelType = Model.GetType();

foreach (PropertyInfo modelField in modelType.GetProperties())
{
%>
<td><%= Html.Display(modelField.Name) %></td>
<%
}
%>
</tr>

しかし、このソリューションには大きな欠陥があります。それは、Clicktricityが投稿したソリューションが、ModelMetadataの詳細(特定のプロパティが表示用に設定されているかどうか、複雑かどうかなど)を認識していることです。

于 2010-10-20T20:21:15.057 に答える