5

ISummaryと呼ばれるインターフェースを実装するオブジェクトのリストがあると想像してください。このリスト内のオブジェクトには、追加のプロパティがある場合があります。

public interface ISummary {
  Guid Id {get;set;}
  string Title {get;set;}
  DateTime Created {get;set;}
}

public class GigSummary: ISummary {
 Guid Id {get;set;}
 string Title {get;set;}
 DateTime Created {get;set;}
 string VenueName {get;set}
 string Band {get;set;}
}

public class NewsSummary: ISummary {
 Guid Id {get;set;}
 string Title {get;set;}
 DateTime Created {get;set;}
 string Author{get;set}
}

ここで、このギグとニュースの概要オブジェクトのリストを(ISummaryのリストとして)モデルとしてビューに渡します。

リストに含まれるタイプごとに異なるパーシャルを使用して、このリストをレンダリングしたいと思います。

これをASP.NETMVCで行うにはどうすればよいですか?

4

5 に答える 5

8

私が考えることができる最も明白な方法は、次のようなことをすることです。

    foreach(ISummary summ in listOfISummary) {
    Html.RenderPartial(String.Fomat("~/Views/Shared/{0}Renderer.ascx", summ.GetType.ToString()), summ, ViewData);%>
}

NewsSummaryRenderer.ascxのように、命名規則を使用して強く型付けされたビューを作成します。

これをヘルパーメソッドに移動できると思いますが、前に提案したようにコードビハインドに配置するのではなく、拡張メソッドを使用して既存のヘルパーの1つに追加します。

于 2009-06-05T13:32:37.130 に答える
0

ビューのコードビハインドにヘルパーメソッドを配置して、次のようにすることができます。

Type modelType = this.Model.GetType();

if (modelType == typeof(NewsSummary))  this.RenderPartial("newspartial", this.Model as NewsSummary);
else if (modelType == typeof(GigSummary)) this.RenderPartial("gigpartial", this.Model as GigSummary);
于 2009-06-05T13:27:38.823 に答える
0

ルイスは正しい方向に進んでいます。私は少し異なる方法を取ります。両方の「ウィジェット」を、関連するビュー名に関する情報を提供する共通の基本クラスから拡張します。次に、ページクラスに拡張メソッドを追加して、適切なビューを配置できる「レンダリングウィジェット」を作成します。

この概念の実用的な例については、KonaASP.NETMVCサンプルアプリを確認してください。

于 2009-06-05T13:36:23.283 に答える
0

これを行うHtmlHelper拡張機能を作成します。これは、c#のように驚くほどに見え、実際に機能する可能性のあるいくつかの擬似コードです。

public static void TemplatedList<T>(this HtmlHelper me, IEnumerable<T> items, 
IDictionary<Type, Action<T>> templates)
{
  foreach(var item in items)
  {
    var template = templates[item.GetType()];
    if(template != null) template(item);
  }
}

私はそれを次のように使用します:

<% HtmlHelper.TemplatedList(ViewData.Model, new Dictionary
  {
    {typeof(GigSummary), x => %>

<div class="gigSummary">
SUP!  GIG ANNOUNCEMENT FOR <%= x.Band %>!!

What:  <%= x.Title %>
When: <%= x.Created %>
Who: <%= x.Author %>
</div>

    <%}
  // add more type/template pairs here
  }); %>
于 2009-06-05T13:37:59.037 に答える
0

必要なタイプだけを抽出するために作成できる簡単な拡張メソッドは次のとおりです。

public static class Extensions
{
    public static IEnumerable<U> ExtractOfType<U, T>(this IEnumerable<T> list)
        where T : class
        where U : class
    {
        foreach (var item in list)
        {
            if (typeof(U).IsAssignableFrom(item.GetType()))
            {
                yield return item as U;
            }
        }
    }
}

テスト:

public interface IBaseInterface
{
    string Foo { get; }
}

public interface IChildInterface : IBaseInterface
{
    string Foo2 { get; }
}

public interface IOtherChildIntreface : IBaseInterface
{
    string OtherFoo { get; }
}

public class BaseImplementation : IBaseInterface
{
    public string Foo { get { return "Foo"; } }
}

public class ChildImplementation : IChildInterface
{
    public string Foo2 { get { return "Foo2"; } }
    public string Foo { get { return "Foo"; } }
}

public class OtherChildImplementation : IOtherChildIntreface
{
    public string OtherFoo { get { return "OtherFoo"; } }
    public string Foo { get { return "Foo"; } }
}

...。

        List<IBaseInterface> b = new List<IBaseInterface>();
        b.Add(new BaseImplementation());
        b.Add(new ChildImplementation());
        b.Add(new OtherChildImplementation());
        b.Add(new OtherChildImplementation());


        foreach (var s in b.ExtractOfType<IOtherChildIntreface, IBaseInterface>())
        {
            Console.WriteLine(s.GetType().Name);
        }

これにより、探している派生タイプのリスト内のすべてのアイテムが取得されます。したがって、コントローラーで、リスト全体をビューに渡します。次に、部分的に必要なタイプのIEnumerableを取得する部分ビューを作成し、メインビュー内でこの拡張メソッドを呼び出して、結果をそれらの個々の部分ビューに渡します。

于 2009-06-05T13:40:01.217 に答える