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.