Passer des ViewData supplémentaires à une vue partielle fortement typée

174

J'ai une vue partielle fortement typée qui prend un ProductImage et quand il est rendu, je voudrais également lui fournir des ViewData supplémentaires que je crée dynamiquement dans la page contenant. Comment puis-je transmettre à la fois mon objet fortement typé et mes ViewData personnalisés à la vue partielle avec l'appel RenderPartial?

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

Réponses:

251

RenderPartial prend un autre paramètre qui est simplement un ViewDataDictionary. Vous y êtes presque, appelez-le comme ceci:

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

Notez que cela remplacera les ViewData par défaut que toutes vos autres vues ont par défaut. Si vous ajoutez quelque chose à ViewData, ce ne sera pas dans ce nouveau dictionnaire que vous passerez à votre vue partielle.

womp
la source
2
J'essaye de faire ceci et il retourne "ne peut pas convertir le vide en objet".
programad
4
@programad Essayez de supprimer le @ de @ Html.RenderPartial (), cela a résolu ce problème pour moi, mais j'appelais RenderPartial () sur une ligne dans un bloc de code @ {}.
danjarvis le
5
Je recommande de consulter la réponse de ctorx ci-dessous. Il ajoute des données supplémentaires aux ViewData existants.
raRaRa
162

Pour étendre ce que womp a publié, vous pouvez transmettre de nouvelles données de vue tout en conservant les données de vue existantes si vous utilisez la surcharge de constructeur de ce ViewDataDictionarytype:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 
ctorx
la source
3
cela peut être très utile si vous devez conserver TemplateInfo.HtmlFieldPrefixle contrôle enfant qui sera réinitialisé sinon
Simon_Weaver
12
C'est certainement la meilleure solution. La perte de ViewData signifie que vous perdez le ModelState et toutes les validations. +1
Kevin Farrugia
Cela semble fonctionner uniquement si vous ne transmettez pas de TemplateInfo.HtmlFieldPrefix dans votre ViewDataDictionary. Je ne peux passer qu'une variable comme illustré sur la réponse, ou passer un TemplateInfo.HtmlFieldPrefix mais pas les deux.
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" } });}

Page partielle (_Header):

<div class="row titleBlock">
    <h1>@ViewData["HeaderName"].ToString()</h1>
    <h5>@ViewData["TitleName"].ToString()</h5>
</div>
muthuvel
la source
2
Cela semble être la réponse la plus complète (bien que le .ToString () ne soit pas nécessaire).
Colin
9

Je pense que cela devrait fonctionner non?

ViewData["currentIndex"] = index;
Joël Martinez
la source
6
Bien que ce ne soit pas une façon très efficace de le faire, cela m'a aidé à comprendre comment récupérer une valeur de données de vue à partir de la réponse de Womp.
Mathias Lykkegaard Lorenzen
6

Créez une autre classe qui contient votre classe fortement typée.

Ajoutez vos nouveaux éléments à la classe et renvoyez-les dans la vue.

Ensuite, dans la vue, assurez-vous d'hériter de votre nouvelle classe et de modifier les bits de code qui seront désormais erronés. à savoir les références à vos champs.

J'espère que cela t'aides. Sinon, faites-le moi savoir et je publierai un code spécifique.

griegs
la source
4

Le moyen le plus simple de transmettre des données supplémentaires consiste à ajouter les données aux ViewData existants pour la vue sous forme de notes @Joel Martinez. Cependant, si vous ne souhaitez pas polluer votre ViewData, RenderPartial a une méthode qui prend trois arguments ainsi que la version à deux arguments que vous affichez. Le troisième argument est un ViewDataDictionary. Vous pouvez créer un ViewDataDictionary distinct uniquement pour votre partiel contenant uniquement les données supplémentaires que vous souhaitez transmettre.

Tvanfosson
la source
1

Cela devrait également fonctionner.

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

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 
MithunChopda
la source
Merci! Ceci est vraiment utile lorsque vous étendez le dictionnaire ViewData pour les partiels enfants, etc.
developius le
1

Je sais que c'est un ancien article, mais je l'ai rencontré face à un problème similaire en utilisant le noyau 3.0, j'espère que cela aidera quelqu'un.

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

<partial name="_Partial" for="PartialViewModel" view-data="ViewData" />
Drytin
la source
0

Vous pouvez utiliser la variable dynamique ViewBag

ViewBag.AnotherValue = valueToView;
Jack1987
la source