Reputation: 9702
There is a requirement to share list items (li) among multiple unordered lists (ul).
The current solution is to create a PartialView for each group of list items to be shared, for example:
@*PartialViewOne*@
<li>item1</li>
<li>item2</li>
<li>item3</li>
@*PartialViewTwo*@
<li>item1</li>
<li>item2</li>
@*ViewOne*@
<ul class="CustomClassONE">@Html.Partial("PartialViewOne")</ul>
@*ViewTwo*@
<ul class="CustomClassTWO">@Html.Partial("PartialViewOne")</ul>
Since there are many list items groups, this will require creating many PartialViews. Not that it is difficult to create them but just looking for more efficent way of accomplishing the same thing. What alternatives are out there for using the above technique?
Upvotes: 0
Views: 1782
Reputation: 9702
Another robust alternative as well is to use JQuery to extract html fragments from the SharedPartialView and inject them into the Views:
<!-- LayoutView -->
<!-- load fragments/lists PartialView in a hidden div-->
<div style="display:none">@Html.Partial("SharedPartialView")</div>
<!-- append appropriate fragments to multiple elements using JQuery -->
<script type="text/javascript">
$(document).ready(function () {
var test = $("#ListA").contents();
test.appendTo("#ulOne, #ulTwo");
});
</script>
<!-- ViewOne -->
<ul id="ulOne">
</ul>
<!-- ViewTwo -->
<ul id="ulTwo">
</ul>
<!-- SharedPartialView that includes all lists -->
<ul id="ListA">
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
<ul id="ListB">
<li>item1</li>
<li>item2</li>
</ul>
Upvotes: 0
Reputation: 9702
This is not an alternative to PartialViews but rather to the way PartialViews are traditionaly used. Tested and was inspired by the following thread. Very interesting approach for extracting static html fragments from a single PartialView.
<!-- ViewOne -->
<ul>
@Html.Partial("SharedPartialView", "ListA")
</ul>
<!-- ViewTwo -->
<ul>
@Html.Partial("SharedPartialView", "ListA")
</ul>
<!-- SharedPartialView that includes all list items -->
@if (Model == "ListA")
{
<li>item1</li>
<li>item2</li>
<li>item3</li>
}
@if (Model == "ListB")
{
<li>item1</li>
<li>item2</li>
}
Upvotes: 0
Reputation: 2776
I would advice to create those lists using Controllers and add them to viewmodels for the pages you use, probably create some class that will return a collection of items on demand and put these items to viewmodel. Then display them using .ComboBoxFor(x=>...)
Something like this:
public ActionResult Index() {
var viewModel = new ViewModel();
viewModel.ListItems = listItemFactory.GetItemsForFirstCase(); //populate items you use in your example as PartialViewOne
return View(viewModel);
}
public ActionResult Search() {
var viewModel = new ViewModel();
viewModel.ListItems = listItemFactory.GetItemsForSecondCase();//populate items you use in your example as PartialViewTwo
return View(viewModel);
}
This way your view code will be much cleaner - you will need 1 partial / DisplayTemplate / EditorTemplate for all cases, and all data can be combined in any way you will need.
Upvotes: 3
Reputation: 218942
If the type of data you want to display in the partial are same, you may create a viewmodel to represent that,
public class MyCustomList
{
public string ListHeader {set;get;}
public List<string> Items {set;get;}
public MyCustomList()
{
Items= new List<string>();
}
}
Then add new properties of this type to your other viewmodels as needed
public class CustomerDetailsVm
{
public string FirstName {set;get;}
public MyCustomList RecentOrders {set;get;}
}
public class ProductDetails
{
public string ProductCode {set;get;}
public MyCustomList SimilarProducts {set;get;}
}
And in your Action methods, you will set your view/action specific values to this property
public ActionResult CustomerDetail(int id)
{
var vm = new CustomerDetailsVm { FirstName = "Shyju" };
vm.RecentOrders = new MyCustomList
{
ListHeader = "Recent Orders",
Items = new List<string>
{
"IPad",
"Beer"
}
};
return View(vm);
}
public ActionResult ProductDetail(int id)
{
var vm = new ProductDetails { ProductCode = "Accord" };
vm.SimilarProducts = new MyCustomList
{
ListHeader = "Similar Products",
Items =new List<string>
{
"Altima",
"Camry"
}
};
return View(vm);
}
And in your views
@model ProductDetails
<h2>@Model.ProductCode</h2>
@Html.Partial("ListPartial",Model.SimilarProducts)
and
@model CustomerDetailsVm
<p>@Model.FirstName</p>
@Html.Partial("ListPartial",Model.RecentOrders)
And your partial view will be strongly typed to our MyCustomList
viewmodel
@model MyCustomList
<h1>@Model.ListHeader</h1>
<ul>
@foreach(var item in Model.Items)
{
<li>@item</li>
}
</ul>
Upvotes: 1