2015-10-13 4 views
1

Я задал вопрос, похожий на этот вопрос, но я не верю, что он четко сформулировал мой вопрос правильно. Итак, вот лучшее объяснение!Проводка модели обратно в контроллер, содержащий сложную коллекцию

Я работаю над приложением C# MVC 5. У меня есть страница, которая динамически перечисляет свойство коллекции модели A. Каждый элемент в этой коллекции использует бит начальной загрузки, чтобы показать/скрыть его собственное свойство коллекции B. Поэтому просто для того, чтобы уточнить, что: Эта модель имеет набор объектов, каждый из которых имеет набор связанных с ним объектов. У этих объектов есть флажок, связанный с ними, связанный с isChecked boolean, который также может использоваться для выбора/отмены выбора элементов. Проверка коробки товара из коллекции A, автоматически выбирает все флажки своей коллекции B. Таким образом, как вы можете видеть, единственная цель - установить флажок в коллекции A элементов, будет действовать как выбор всего для связанной коллекции 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%) Я заставил идентификаторы для этих скрытых полей, чтобы они соотносились с идентификаторами флажков. Может быть, не самая лучшая идея, но это было только последнее, что я пытался получить эту работу ...

Теперь у меня есть два варианта здесь:

1) Верь в выше означает, что всякий раз, когда флажок выбран/отменен, объект в коллекции, с которой он связан, получит его isChecked boolean изменено. Затем POST вернет всю модель и надеюсь, что я смогу пройти через все проверенные предметы и сделать потрясающие вещи.

или

2) Создать свойство строки в модели, чтобы провести JSON представление этого сложного набора объектов. Когда страница POSTED, обновите эту строку JSON до состояния сложной коллекции, которая, как мы надеемся, будет обновлена, чтобы некоторые из ее элементов были проверены/сняты. Затем POST вернет всю модель и серверную сторону, я бы десериализовал этот единственный объект в логически эквивалентную сложную коллекцию и работал оттуда. I.e. Моя смена модели будет добавить свойство:

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

Попытка решения A, я либо получить нуль для свойства «Категории», или если я добавляю @ Html.HiddenFor (d => d.Categories); Я получаю пустой объект, счет 0.

Попытка решения B, я получаю прекрасное представление JSON для сложных категорий обратно в сервере земле, но я вижу, флажки я проверил, не изменяя Bools IsChecked ведущих меня полагать, что, в то время как объект JSON является который может быть установлен на объект «Категории» на стороне клиента POST, все, что сделано пользователем, не сохраняется, поэтому в конечном итоге коллекция «Категории» модели не изменилась с тех пор, как она была первоначально передана в представление.

Извините, если все это кажется сложным, это и для младшего, как я, я подумал, что лучше всего спросить, поскольку я никогда раньше не отправлял списки и прочее на контроллер.

Я был бы рад предоставить дополнительную информацию, если это поможет!

Сердечный привет,

+0

Вы не можете использовать 'foreach' петли или' ElementAt (I) 'для создания элементов управления формы, которые будут связываться с коллекциями. Ваши генерирующие атрибуты 'name' без индексаторов, которые не имеют отношения к вашей модели. Вам необходимо внедрить 'IList ', и вам нужно использовать вложенные петли for for (или, альтернативно, использовать собственные шаблоны EditorTemplates для ваших типов. –

ответ

1

Если вы измените Foreach петли для для петель вы можете использовать индекс цикла в лямбда-выражения. Это должно заставить двигатель выводить правильный синтаксис для публикации значений. Например:

@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

Спасибо за все ваши предложения. Я пошел по шаблону шаблона редактора и рад сообщить, что мой теперь у меня есть все, что мне нужно! Вы, сэр, герой! –