简体   繁体   中英

Need to pass Viewbag and TemplateInfo to partial view in MVC

So the question of how to pass Viewbag data to a partial view has been answered on here multiple times, but I need to pass the viewbag info and the TemplateInfo to my partial view and I can't find a single question that deals with that. Part of my controller looks like this.

<div>
    @{Html.RenderPartial("AboutActivity", (Transport.Models.Tracking.TravelRequest.AboutActivityModel)Model,
              new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "AboutActivity" } });}
</div>

This works fine in mapping my objects back to the model and all, but I have a few views that need to load dropdowns from the ViewBag data as so.

@Html.DropDownList("Destination.State", (IEnumerable<SelectListItem>)ViewBag.States)

How can I pass both the ViewBag data and the TemplateInfo prefix to.

You do not need to explicitly pass the ViewBag data from your main view to your partial view. As long as you have it available in your main view( that means you set the ViewBag data in your GET action ), It will be available in the partial view as well.

public ActionResult Index()
{
   var states = new List<SelectListItem>
   {
        new SelectListItem {Value = "MI", Text = "MI"},
        new SelectListItem {Value = "OH", Text = "MOH"}           
   };
   ViewBag.States = states;
   return view();
}

And in your Index and the partial view which is being invoked from the Index view, ViewBag.States is accessible.

Index view

@Html.DropDownList("Destination.State", (IEnumerable<SelectListItem>)ViewBag.States)
<div>
    @{ Html.RenderPartial("AboutActivity"); }
</div>

Partial view (AboutActivity )

<h2>My PartialView</h2>
@Html.DropDownList("Destination.State", (IEnumerable<SelectListItem>)ViewBag.States)

A better solution is to not use dynamic stuff like ViewBag and ViewData to pass data between action methods and views. Why not add a new property to your view model of type List<SelectListItem> for the dropdown data and use that ?

public class AboutActivityViewModel
{
  public List<SelectListItem> States {set;get;}
  public int SelectedState {set;get;}    
  // Other properties for the view as needed
}

public ActionResult Index()
{
   var vm = new AboutActivityViewModel();
   vm.States = new List<SelectListItem>
   {
        new SelectListItem {Value = "MI", Text = "MI"},
        new SelectListItem {Value = "OH", Text = "MOH"}           
   };      
   return view(vm);
}

And your view which is strongly typed to AboutActivityViewModel

@model AboutActivityViewModel
<div>
    @{ Html.RenderPartial("AboutActivity"); }
</div>

And in your Partial view, which is also strongly typed.

@model AboutActivityViewModel     
@Html.DropDownListFor(f => f.SelectedState, Model.States)

If you do not pass a model to the partial view explicitly, It will use the model of the parent page from it is called.

In your case, you are passing a totally new ViewDataDictionary to the partial which will overwrite the States you set to the ViewBag earlier. So you should make sure that you are reading the States from existing ViewBag and set that to the new ViewDataDictionary you are passing.

<div>

    @{ Html.RenderPartial("AboutActivity", Model, new ViewDataDictionary
        {
            TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "AboutActivity" },
            ["States"] = ViewBag.States
        });
     }
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM