Przekaż dodatkowe ViewData do widoku częściowego z silną typizacją


174

Mam mocno wpisany Widok częściowy, który pobiera ProductImage i kiedy jest renderowany, chciałbym również udostępnić mu dodatkowe ViewData, które tworzę dynamicznie na stronie zawierającej. Jak mogę przekazać zarówno mój obiekt o jednoznacznie określonym typie, jak i moje niestandardowe ViewData do widoku częściowego za pomocą wywołania RenderPartial?

var index = 0;
foreach (var image in Model.Images.OrderBy(p => p.Order))
{
  Html.RenderPartial("ProductImageForm", image); // < Pass 'index' to partial
  index++;
}

Odpowiedzi:


251

RenderPartial przyjmuje inny parametr, który jest po prostu ViewDataDictionary. Już prawie gotowe, po prostu nazwij to tak:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary { { "index", index } }
); 

Zwróć uwagę, że spowoduje to przesłonięcie domyślnych ViewData, które domyślnie mają wszystkie inne widoki. Jeśli dodajesz cokolwiek do ViewData, nie będzie to w nowym słowniku, który przekazujesz do widoku częściowego.


2
Próbuję to zrobić i zwraca „nie można przekształcić void w obiekt”.
— programad

4
@programad Spróbuj usunąć @ z @ Html.RenderPartial (), to rozwiązało ten problem, ale wywoływałem RenderPartial () w wierszu wewnątrz bloku kodu @ {}.
— danjarvis

5
Polecam sprawdzić odpowiedź ctorx poniżej. Dodaje dodatkowe dane do istniejących ViewData.
— raRaRa

162

Aby przedłużyć na co womp pisał, to może przekazać nowy widok danych przy zachowaniu istniejącego widoku danych, jeśli użyć przeciążenie konstruktora ViewDataDictionarytak:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 

3
może to być bardzo przydatne, jeśli chcesz zachować TemplateInfo.HtmlFieldPrefixkontrolę podrzędną, która zostanie zresetowana w przeciwnym razie
— Simon_Weaver

12
To zdecydowanie lepsze rozwiązanie. Utrata ViewData oznacza utratę ModelState i wszystkich walidacji. +1
— Kevin Farrugia

Wydaje się, że działa to tylko wtedy, gdy nie przekażesz TemplateInfo.HtmlFieldPrefix w swoim ViewDataDictionary. Mogę tylko przekazać zmienną, jak pokazano w odpowiedzi, lub przekazać TemplateInfo.HtmlFieldPrefix, ale nie oba.
— Ferox,

45
@Html.Partial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } })
or
@{Html.RenderPartial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } });}

Częściowa strona (_Header):

<div class="row titleBlock">
    <h1>@ViewData["HeaderName"].ToString()</h1>
    <h5>@ViewData["TitleName"].ToString()</h5>
</div>

2
Wydaje się, że jest to najbardziej kompletna odpowiedź (chociaż .ToString () jest niepotrzebna).
— Colin,

9

Myślę, że to powinno działać, nie?

ViewData["currentIndex"] = index;

6
Chociaż nie jest to zbyt mocny sposób, aby to zrobić, pomógł mi dowiedzieć się, jak odzyskać wartość danych widoku z odpowiedzi Wompa.
— Mathias Lykkegaard Lorenzen

6

Utwórz kolejną klasę, która zawiera klasę o jednoznacznie określonym typie.

Dodaj nowe rzeczy do klasy i zwróć je w widoku.

Następnie w widoku upewnij się, że odziedziczyłeś nową klasę i zmień bity kodu, które teraz będą błędne. mianowicie odniesienia do twoich dziedzin.

Mam nadzieję że to pomoże. Jeśli nie, daj mi znać, a prześlę konkretny kod.


4

Najłatwiejszym sposobem przekazania dodatkowych danych jest dodanie danych do istniejących ViewData dla widoku jako notatki @Joel Martinez. Jeśli jednak nie chcesz zanieczyszczać swoich ViewData, RenderPartial ma metodę, która przyjmuje trzy argumenty, a także wyświetlaną wersję dwuargumentową. Trzeci argument to ViewDataDictionary. Możesz utworzyć oddzielny ViewDataDictionary tylko dla części zawierającej tylko dodatkowe dane, które chcesz przekazać.


1

To też powinno działać.

this.ViewData.Add("index", index);

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 

Dzięki! Jest to bardzo przydatne, gdy jesteś rozszerzenie słownika ViewData dla partials dziecko etc
— developius

1

Wiem, że to stary post, ale natknąłem się na niego, gdy miałem podobny problem z rdzeniem 3.0, mam nadzieję, że komuś pomoże.

@{
Layout = null;
ViewData["SampleString"] = "some string need in the partial";
}

<partial name="_Partial" for="PartialViewModel" view-data="ViewData" />

0

Możesz użyć dynamicznej zmiennej ViewBag

ViewBag.AnotherValue = valueToView;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.