2015-10-13 42 views
1

我發佈了一個類似於這個的問題,但我不相信它正確地說明了我的問題。所以這裏有更好的解釋!將模型發回到包含複雜集合的控制器

我正在研究C#MVC 5應用程序。我有一個頁面動態列出模型的集合屬性A。此集合中的每個項目都使用一些引導程序來顯示/隱藏它自己的集合屬性B。所以只是爲了澄清:這個模型有一個對象集合,每個對象都有一個與它相關的對象集合。這些對象每個都有一個複選框,它們綁定到一個isChecked布爾值,可以用來選擇/取消選擇項目。檢查收藏A中的物品的一個框,自動選擇其集合的所有複選框B。因此,您或許可以看到,在收集項目上具有複選框的唯一目的是充當其關聯集合B項目的全選。

我試圖將整個模型傳遞給控制器​​在POST上,然後做它的東西,例如,抓住所有物品,但遇到一些問題。

E.g.

@foreach (var category in Model.Categories) 
{ 
    var headerId = category.Name; 
    var childCounter = 0; 
    @*some divs and headers here*@ 

    @if (category.Items.Any()) 
    { 
    @*lets give it the ability to check all of its associated items*@ 
    @Html.CheckBoxFor(d => category.IsChecked, new {id = @headerId, onclick = String.Format("CheckUncheckChildren({0}, {1})", @headerId, category.MenuItems.Count)}) 
    } 
    else 
    { 
    @Html.CheckBoxFor(d => category.IsChecked) 
    } 

    @*some other divs and headings*@ 
    @if (category.MenuItems.Any()) 
    { 
    @foreach (var item in dealItemCategory.MenuItems) 
    { 
     var childId = childCounter++ + "_" + headerId; 
     var serverId = item.Id; 

     @*some other divs and headings*@ 
     @Html.CheckBoxFor(d => item.IsChecked, new {id = @childId}) 
    } 
    } 
} 

在頁面上低了下去,我有:

for (var i = 0; i < Model.Categories.Count(); i++) 
    {  
    var category = Model.Categories.ElementAt(i); 
    var headerId = category.Name; 
    @Html.HiddenFor(d => category, new {id = @headerId}) 

    for (var j = 0; j < Model.Categories.ElementAt(i).Items.Count(); j++) 
    { 
     var item = Model.Categories.ElementAt(i).Items.ElementAt(j);  
     @Html.HiddenFor(d => item, new {id = j + "_" + @headerId}) 
    } 
    } 

在我的腦海裏,我保留在頁面上這些屬性對於這個複雜的集合......(不,我的理解是100% )我已經爲這些隱藏的字段強制使用了id,以便它們與複選框的ID相關聯。也許不是最好的辦法,但它只是我試圖得到這個工作的最後一件事...

現在我這裏有兩個選擇:

1)相信在上面的意思是,只要選中/取消選擇複選框,與其關聯的集合中的對象將獲取其isChecked布爾值已更改的對象。然後,發回整個模型,並希望我能夠遍歷所有檢查的項目,並做出令人敬畏的東西。

2)在模型中創建一個字符串屬性來保存對象的這種複雜的集合的JSON表示。當頁面POSTED時,將此JSON字符串更新爲希望更新的複雜集合的狀態,以使其某些項目被選中/取消選中。然後,POST將整個模型和服務器端返回,我會將這個單個對象反序列化爲一個邏輯上等效的複雜集合,並從那裏開始工作。 也就是說 我的模型變化將增加一個屬性:

public string JsonCategories{ get; set; } 

然後在視圖我不得不啓動回發:

@Html.HiddenFor(d => d.JsonCategories); 

function accept() { 
    var categories= @Html.Raw(Json.Encode(Model.Categories)); 
    var jsonCategories = JSON.stringify(categories); 
    var a = $('#JsonCategories').val(); 
    $('#JsonCategories').val(jsonCategories); 
    $("form").submit(); 
}; 

試圖解決一個,我要麼得到一個空對於Categories屬性,或者如果我添加@ Html.HiddenFor(d => d.Categories);我得到一個空對象,計數爲0。

試圖溶液B,我得到了複雜的分類早在服務器土地可愛的JSON表示,但我看到的複選框選中我不改變的bool器isChecked導致我相信,而JSON對象能夠在POST客戶端上設置爲Categories對象,因此用戶完成的所有操作都不會保留,因此最終該模型的Categories集合從最初傳遞給View以來未發生任何更改。

對不起,如果這一切看起來很複雜,它是和像我這樣的初中,我認爲最好的問我周圍,因爲我從來沒有向控制器發佈過列表和東西。

如果能提供幫助,我很樂意提供更多信息!

向那,

+0

不能使用'foreach'環或'的ElementAt(我)'生成將綁定到集合表單控件去。您生成的'name'屬性沒有與您的模型沒有任何關係的索引器。你需要實現'IList ',你需要使用嵌套'for'循環(或者爲你的類型使用自定義EditorTemplates –

回答

1

如果你改變你的foreach循環,爲循環您可以使用循環索引的lambda表達式。這應該使引擎輸出發佈值的正確語法。例如:

@for (int i = 0; i < Model.Categories.Count(); i++) 
{ 
    ... 
    @Html.CheckBoxFor(d => d.Categories[i].IsChecked) 
    ... 
} 

這應該正確地將值綁定到POST請求。生成的HTML將類似於下面的代碼片段(0是第一項,1是第二等):

<input name="Categories[0].IsChecked" ... ></input> 

另外,您可以爲您的孩子打造集編輯模板,這將導致你寫出這個片段來取代你的for循環當前的位置。

@Html.EditorFor(m => m.Categories) 

更多關於如何做到這一點here

這應該幫助你選擇1

+0

感謝你的所有建議。我已經走了編輯器模板路線,很高興地宣佈我的模型現在擁有我需要的一切!你是先生,是英雄! –

相關問題