16

Utworzono następujący niestandardowy ActionResult, który zwraca wiele widoków częściowych.Niestandardowy odpowiednik odpowiednika dla wszystkich częściowych widoków

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); 
     } 
    } 
} 

A potem używać go w sposób następujący:

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

Ale jeśli I miejsce przerwania w konstruktorze MultiplePartialViewsResult „s widzę ten model w obu przypadkach wynosi 2.0. Zastępuje wszystkie modele ostatnim modelem określonym w tablicy.

Spróbuj utworzyć parę PartialViews w metodzie i przypisz ją do zmiennej. Wtedy zauważysz, że wszyscy mają podobny model.

+1

Tak, to jest poprawne. Jeśli próbujesz zwrócić dwa "modele" do jednego widoku, utwórz "model widoku", który zawiera oba modele, które chcesz wysłać, i uczyń model widoku nowym 'ViewModel' –

+0

To jest punkt, do którego próbuję wrócić do wielu widoków. Idea opiera się na tym poście, w którym autor wskazuje, że modele mogą być różne. https://www.simple-talk.com/dotnet/asp.net/revisiting-partial-view-rendering-in-asp.net-mvc/ – Maximus

+1

Czy sprawdzasz ostatnie rzeczy? Mówi się, aby użyć 'widoku modelu 'współdzielonego przez oba widoki częściowe. –

Odpowiedz

6

można zainicjować MultiplePartialViewsResult obiekt w następujący sposób z nowej własnejViewData/ViewData.Model instancji (działa dobrze dla mnie):

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 } } } 
); 

niestandardową akcję Wynik:

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); 
     } 
    } 
} 

Kontroler:

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 } } } 
    ); 
} 

Views:

Index:

@Html.Action("FakeAction") 

ColumnSumView.cshtml/RowSumView.cshtml:

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

To obejście problemu, ale zastanawiam się, dlaczego mój przykład nie działa. Czy istnieje lepsze podejście do przekazywania wielu widoków częściowych? – Maximus

+0

Wygląda na to, że jest on związany z przechowywaniem obiektu ViewData/Model podczas renderowania PartialView (pojedynczego ViewData na ActionResult). Być może jest to oczekiwane zachowanie. Postaram się sprawdzić, czy istnieje lepsze rozwiązanie. Na razie możesz użyć mojego sugerowanego podejścia i zawsze inicjować każdy ActionResult/PartialViewResult przy pomocy nowej instancji ViewData/Model. – Mikhail

+3

Dzieje się tak z powodu ['PartialView'] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Controller.cs) pomocnika kontrolera, który został użyty do utworzenia każdego wyniku częściowego. Ten pomocnik ustawi model w ViewData.Model gdzie ViewData jest właściwością w [kontroler] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ControllerBase.cs). Wywołanie dwa razy 'PartialResult' zastąpi ViewData.Model –