16

次のカスタムActionResultを作成し、複数の部分ビューを返します。すべてのPartialViewsのカスタムActionResult相当モデル

public class MultiplePartialViewsResult : ActionResult 
{ 
    private const string Separator = "-"; 
    private PartialViewResult[] _partialViews; 

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews) 
    { 
     _partialViews = partialViews; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     foreach (var partialView in _partialViews) 
     { 
      partialView.ExecuteResult(context); 
      context.HttpContext.Response.Output.Write(Separator); 
     } 
    } 
} 

そして、次のように私はそれを使用する:

return new MultiplePartialViewsResult(
      PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
      PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 })); 

をしかし、私はMultiplePartialViewsResultのコンストラクタにブレークポイントを置く場合、私は両方のケースでモデルが2.0に等しいことがわかります。これは、配列で指定された最後のモデルを持つすべてのモデルをオーバーライドします。

メソッド内にいくつかのPartialViewを作成し、変数に割り当てるようにしてください。そして、あなたはそれらがすべて同等のモデルを共有していることに気づくでしょう

+1

はい、正しいです。2つの 'model'を1つのビューに戻そうとする場合は、両方のモデルを含む' view model'を作成し、ビューのモデルを新しい 'ViewModel'にします。 –

+0

それは、私が多くの意見に戻そうとしているところです。イデアは、この記事に基づいています。 https://www.simple-talk.com/dotnet/asp.net/revisiting-partial-view-rendering-in-asp.net-mvc/ – Maximus

+1

最後に確認したことがありますか? 'partial view'の両方で共有される' view model'を使うと言います。 –

答えて

6

あなたは(私のために正常に動作します)新しい自分のViewDataで/ViewData.Modelインスタンスを次のようにMultiplePartialViewsResultオブジェクトを初期化することができます。

return new MultiplePartialViewsResult(
    //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
    //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 }) 
    new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } }, 
    new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } } 
); 

カスタムアクションの結果を:

public class MultiplePartialViewsResult : ActionResult { 
    private const string Separator = "-"; 
    private PartialViewResult[] _partialViews; 

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews) { 
     _partialViews = partialViews; 
    } 

    public override void ExecuteResult(ControllerContext context) { 
     foreach(var partialView in _partialViews) { 
      partialView.ExecuteResult(context); 
      context.HttpContext.Response.Output.Write(Separator); 
     } 
    } 
} 

コントローラ:

public ActionResult Index() { 
    return View(); 
} 
public ActionResult FakeAction() { 
    return new MultiplePartialViewsResult(
     //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
     //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 }) 
     new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } }, 
     new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } } 
    ); 
} 

再生回数:

インデックス:

@Html.Action("FakeAction") 

ColumnSumView.cshtml/RowSumView.cshtml:

@model List<double> 
<ul> 
    @foreach(double item in Model) { 
     <li>@item</li> 
    } 
</ul> 
+0

これは回避策ですが、なぜ私の例がうまくいかないのか不思議です。複数の部分ビューを渡す方が良いでしょうか? – Maximus

+0

PartialView(ActionResultごとに1つのViewData)をレンダリングしているときに、ViewData/Modelオブジェクトを保持することに関連しているようです。おそらく、これは予想される動作です。よりよい解決策があるかどうかをチェックしようとします。今のところ私の提案するアプローチを使用し、常に新しいViewData/Modelインスタンスで各ActionResult/PartialViewResultを初期化することができます。 – Mikhail

+3

これは、['PartialView'](https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Controller)のために発生します。cs)helperを使用して、各部分結果を作成するために最大値が使用されました。そのヘルパーはViewData.Modelでモデルを設定します.ViewDataは[コントローラ](https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ControllerBase.cs)のプロパティです。 'PartialResult'を2回呼び出すと、ViewData.Modelがオーバーライドされます。 –