2011-12-17 25 views
0

我使用的是asp.net mvc 3,並且認爲處理這種情況的最好方法是。視圖模型綁定如何工作? +使用視圖模型處理動態控件的最佳方式?

說我有一個創建獎勵結構的表單。在這種情況下,他們可以獎勵

例如

$100 to $500 - get .05% back 
$501 to $1000 - get 0.6% back 
$1001 to $1001 - get 0.7% back 
and so forth. 

現在,這些層在我創建表單中輸入的多層次。可能有一個獎勵層,或者可能有5層或50層。我只是不知道。

選項1

製作的人工限制說5層。如果他們只需要一個層次,他們仍然需要通過嚮導表單(通過jQuery),我正在創建並跳過下一個4層屏幕(他們需要填寫很多字段,所以我決定做出來一個巫師,所以它不會一下子壓倒一切)。

public class MasterVm 
    { 
     public IList<TiersVm> Tiers { get; set; } 

     public MasterVm() 
     { 
      Tiers = new List<TiersVm>(); 
     } 
    } 

@for (int i = 0; i < Model.Tiers.Count; i++) 
{ 
    @Html.LabelFor(x => x.Tiers[i].StartOfRange, "Start Of Range") 
    @Html.TextBoxFor(x => x.Tiers[i].StartOfRange) 

    @Html.LabelFor(x => x.Tiers[i].EndOfRange, "End Of Range") 
    @Html.TextBoxFor(x => x.Tiers[i].EndOfRange) 

    // more fields here 

} 

在我的控制器中,我會做5個佔位符,所以for循環會去5次左右。

選項2

使窗體具有產生另一層按鈕。他們點擊它,另一層將被製作。這樣,如果他們只有一個,他們只能看到一次,如果他們有100個,這並不重要。

我想使用jQuery克隆來實現這一點,但我真的不知道視圖模型綁定是如何工作的。它看起來是ID嗎?或名字?

當我做一個選擇我的所有控件看起來像這樣

<input id="Tiers_0__StartOfRange" type="text" value="0" name="Tiers[0].StartOfRange"> 

它們都具有唯一的ID(什麼是好的)和唯一的名稱。我不確定在克隆代碼中是否應該刪除ID和名稱。還是我需要在那裏有代碼來生成id和上面的名字?

我將通過使用jquery.serializeArray()通過ajax提交這一切,並在控制器中我將有一個參數與視圖模型也應該綁定。

回答

1

我不喜歡開箱即用的集合索引模式MVC3使用。在我們的應用程序中,我們使用Steve Sanderson's BeginCollectionItem HTML helper。它覆蓋默認行爲並使用GUID而不是整數來索引多個項目。

我建議你做選項#2,但在服務器上做克隆/收集項目工廠的東西,並只是使用Ajax將HTML返回到視圖。 Steve的助手使用默認的模型綁定器,因此當您發佈表單時,最終將從表單輸入綁定一系列層模型。對於單層

樣品局部視圖:

@model TiersVm 
<div class="tier-item"> 
@using(Html.BeginCollectionItem("Tiers")) 
{ 
    Html.LabelFor(x => x.StartOfRange, "Start Of Range") 
    Html.TextBoxFor(x => x.StartOfRange) 

    Html.LabelFor(x => x.EndOfRange, "End Of Range") 
    Html.TextBoxFor(x => x.EndOfRange) 

    // more fields here 
} 
</div> 

你將不得不當用戶點擊「添加層」按鈕,返回上述部分的操作方法。

public PartialViewResult GenerateTier() 
{ 
    return PartialView(new TiersVm()); 
} 

的BeginCollectionItem助手將會使你所有的輸入姓名和身份證的,使他們可以反彈到你的模型張貼在:

@model MasterVm 
... using BeginForm .... 

<div class="tier-container"> @* clicking new tier button appends items here *@ 
@foreach (var tier in Model.Tiers) 
{ 
    Html.Action("GenerateTier", "ControllerName") 
} 
</div> 

然後奇蹟發生了與默認的模型綁定

[HttpPost] 
public ActionResult ReceiveInput(MasterVm masterVm) 
{ 
    // masterVm.Tiers has been populated by the default model binder 
} 
+0

嘿,你知道如果有可能具有強類型的BeginCollectionItem()嗎?將會比硬編碼更好。幫手也會更改綁定。我有一個視圖,我有BeginCollectionItem(),我有一個foreach循環,當通過視圖模型的集合。那個人永遠不會再綁定了。我也必須使用BeginCollectionItem()來綁定它。 – chobo2 2011-12-19 21:27:47

+0

你是什麼意思的強類型?你的意思是@using(Html.BeginCollectionItem(「StonglyTypeThis」)){'..?據我所知,沒有。要回答你的其他問題,我不認爲它應該改變默認的模型聯編程序的行爲。它只是使用HTML中的.index隱藏字段作爲集合的索引器。 – danludwig 2011-12-19 22:08:36

+0

我的意思是像Html.BeginCollectionItem(x => x.Tiers)。我有一些問題,我的觀點http://stackoverflow.com/questions/8568160/steve-sandersons-begincollectionitem-helper-wont-bind-correctly我會嘗試一些事情,並試圖看看它是否是這個幫手這是造成它。 – chobo2 2011-12-19 22:11:59

0

準則是元素的ID必須與ViewModel屬性名稱相對應。
其餘的都是你的決定。

如果您創建一個AJAX調用服務器必須使URL參數對應的模型屬性

您可以編寫自定義的模型綁定,根據你所需要的邏輯結合,其中一個例子爲自定義IModelBinder你可以找到here

注意這個MVC團隊建議:

一般情況下,我們建議人們不要寫自定義模型粘合劑 ,因爲他們很難得到正確的,他們是 - [R需要

+0

因此,要麼我必須確保層_ _ __ StartOfRange被設置爲正確的數字或​​編寫一個模型綁定器,可以解決這個問題呢? – chobo2 2011-12-17 20:31:15

+0

@ chobo2,是的,你必須用默認的模型綁定器來管理正確的數字。 – gdoron 2011-12-17 20:32:42

相關問題