2011-06-27 33 views
6

我正在使用MVC3剃鬚刀。我有一個場景,我必須在同一個父視圖上多次使用局部視圖。我遇到的問題是當父視圖呈現時,它會在這些部分視圖中生成相同的輸入控件名稱和ID。由於我的部分視圖綁定了不同的模型,因此當視圖重新發布到「保存」時,它會崩潰。任何想法如何使控制ID /名稱獨特,可能一些如何前綴他們?在同一父視圖上多次使用一個局部視圖

等待

納比爾

回答

5

我個人更喜歡使用的編輯模板,因爲他們照顧這。例如,你可以有以下視圖模型:

public class MyViewModel 
{ 
    public ChildViewModel Child1 { get; set; } 
    public ChildViewModel Child2 { get; set; } 
} 

public class ChildViewModel 
{ 
    public string Foo { get; set; } 
} 

及以下控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      Child1 = new ChildViewModel(), 
      Child2 = new ChildViewModel(), 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

Index.cshtml視圖中:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    <h3>Child1</h3> 
    @Html.EditorFor(x => x.Child1) 

    <h3>Child2</h3> 
    @Html.EditorFor(x => x.Child2) 
    <input type="submit" value="OK" /> 
} 

和最後一部分是編輯模板(~/Views/Home/EditorTemplates/ChildViewModel.cshtml):

@model ChildViewModel 

@Html.LabelFor(x => x.Foo) 
@Html.EditorFor(x => x.Foo) 

使用EditorFor您可以包含模板以查看主視圖模型的不同屬性,並生成正確的名稱/ id。除此之外,您將在POST操作中正確填充您的視圖模型。

2

有一個替代方法:

  1. 添加一個前綴PartialView
  2. 綁定模型,消除前綴

爲1,設置視圖中的前綴:

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "prefix"; 

對於2,您可以使用UpdateModel恢復數據,如下所示:

UpdateModel(producto, "prefix"); 

這不是非常明智的做法,因爲您的操作未收到數據作爲參數,但稍後會更新模型。這有幾個不便之處:1)通過查看其簽名並不清楚你的操作需要什麼2)爲單元測試提供輸入操作並不容易3)操作容易受到溢出參數的影響(用戶提供的參數那不應該在那裏並被映射到模型)。

但是,對於2有一個替代方案:註冊一個自定義模型綁定器,允許您刪除前綴。而定製的模型活頁夾必須知道它。

一個好的解決辦法是在這個SO Q &答:How to handle MVC model binding prefix with same form repeated for each row of a collection?但它有一點瑕疵:如果您添加一個隱藏字段,在局部視圖名稱「__prefix」,並渲染幾次的局部視圖,該ID將在頁面中的多個不同元素上重複,這是不允許的,並且會引起一些麻煩。提供前綴的最重要原因之一就是將實體的多個實例的部分視圖精確地呈現爲相同的「編輯」視圖。即這會發生在像gmail這樣的頁面中,您可以在其中一次編輯多個電子郵件。

有此問題的幾種可能的解決方案。

其中之一是提供前綴作爲查詢字符串或的RouteData值,而不是作爲一個形式字段,其避免ID衝突,並可以由模型粘合劑被發現。 (它可以始終具有相同的名稱)。

另一種解決方案是使用隱藏字段,具有固定的模式,但它是對於每個呈現的視圖不同。前綴可以遵循這個模式的獨特性:「PP $ ActionControllerId」喜歡「PP $ EditProduct23」,這是每個渲染視圖唯一的,可以找一個與「PP $」開頭的請求參數之間很容易被發現。

而且最終的解決辦法是隻在視圖中創建的前綴,而不是提供它在任何類型的請求參數的。模型聯編程序必須查找檢查請求參數名稱的前綴,直到找到其前綴遵循該模式的前綴。

當然,定製模型綁定器必須適應TIEH所選擇的約定工作。

相關問題