部分视图的替代方案

时间:2015-12-14 19:57:58

标签: asp.net-mvc

需要在多个无序列表(ul)之间共享列表项(li)。

目前的解决方案是为每个要共享的列表项创建一个PartialView,例如:

@*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> 

由于列表项组很多,因此需要创建许多PartialViews。并不是说创造它们很困难,而只是寻找更有效的方法来完成同样的事情。使用上述技术有哪些替代方案?

4 个答案:

答案 0 :(得分:3)

我建议使用控制器创建这些列表,并将它们添加到您使用的页面的视图模型中,可能会创建一些类,它将按需返回项集合并将这些项放到viewmodel中。然后使用.ComboBoxFor(x=>...)

显示它们

这样的事情:

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);
}

这样您的视图代码将更加清晰 - 您将需要1个部分/ DisplayTemplate / EditorTemplate用于所有情况,并且所有数据都可以以您需要的任何方式进行组合。

答案 1 :(得分:1)

如果要在partial中显示的数据类型相同,则可以创建一个viewmodel来表示该数据,

import Html exposing (div, button, text)
import Html.Events exposing (onClick)
import StartApp.Simple as StartApp


main =
  StartApp.start { model = model, view = view, update = update }


model = 0


view address model =
  div []
    [ button [ onClick address Decrement ] [ text "-" ]
    , div [] [ text (toString model) ]
    , button [ onClick address Increment ] [ text "+" ]
    ]


type Action = Increment | Decrement


update action model =
  case action of
    Increment -> model + 1
    Decrement -> model - 1 

然后根据需要将此类型的新属性添加到其他视图模型中

public class MyCustomList
{
  public string ListHeader {set;get;}
  public List<string> Items {set;get;}

  public MyCustomList()
  {
    Items= new List<string>();
  }
}

在Action方法中,您将视图/操作特定值设置为此属性

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;}
}

在你的观点中

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);
 }

@model ProductDetails
<h2>@Model.ProductCode</h2>
@Html.Partial("ListPartial",Model.SimilarProducts)

您的部分视图将强烈输入我们的@model CustomerDetailsVm <p>@Model.FirstName</p> @Html.Partial("ListPartial",Model.RecentOrders) viewmodel

MyCustomList

答案 2 :(得分:0)

这不是PartialViews的替代品,而是PartialViews传统使用的方式。经过测试并受到以下thread的启发。从单个PartialView中提取静态html片段的非常有趣的方法。

<!-- 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> 
}

答案 3 :(得分:0)

另一个强大的替代方案是使用JQuery从SharedPartialView中提取html片段并将它们注入到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>