2012-09-12 3 views
2

У меня возникли проблемы с привязкой данных к коллекции элементов коллекции (у меня также возникла проблема с правильной формулировкой моей проблемы). Давайте просто упростим все, используя пример с psudo-моделями.MVC Добавить и удалить элементы из подмножества

Допустим, у меня есть следующие примеры моделей:

public class Month() 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Week> Weeks { get; set; } 
} 

public class Week() 
{ 
    public int ID { get; set; } 
    public int MonthID { get; set; } 
    public String Name { get; set; } 
    public virtual ICollection<Day> Days { get; set; } 
} 

public class Day() 
{ 
    public int ID { get; set; } 
    public String Name { get; set; } 
} 

... и пример ViewModel:

public class EditMonthViewModel() 
{ 
    public Month Month { get; set; } 
    public List<Week> Weeks { get; set; } 
    public List<Day> AllDays { get; set; } 
} 

Цель Edit Action/View является, чтобы позволить пользователям редактировать месяц, недели, назначенные на месяц, и добавьте и удалите дни с недель определенного месяца. Представление может помочь.

@model myProject.ViewModels.EditMonthViewModel 

//... 
@using (Html.BeginForm()) 
{ 
    //Edit Month Stuff... 

    @for(int i = 0; i < Model.Weeks.Count(); i++) 
    { 
     <h2>@Model.Weeks[i].Name</h2> 
     @Html.EditorFor(model => Model.Weeks[i].Name) 

     //loop through all possible days 
     //Select only days that are assigned to Week[i] 
     @for(int d = 0; d < Model.AllDays.Count(); d ++) 
     { 
      //This is the focus of this question. 
      //How do you bind the data here? 
      <input type="checkbox" 
        name="I have no idea" 
        @Html.Raw(Model.Weeks[i].Days.Contains(Model.AllDays[d]) ? "checked" : "") /> 
     } 
    } 
} 

методы контроллера Действие

public ActionResult Edit(int id) 
{ 
    var viewModel = new EditMonthViewModel(); 
    viewModel.Month = db.Months.Find(id); 
    viewModel.Weeks = db.Weeks.Where(w => w.MonthID == id).ToList(); 

    viewModel.AllDays = db.Days.ToList(); 
} 

[HttpPost] 
public ActionResult Edit(EditMonthViewModel viewModel) 
{ 
    var monthToUpdate = db.Months.Find(viewModel.Month.ID); 
    //... 

    if(viewModel.Weeks != null) 
    { 
     foreach (var week in viewModel.Weeks) 
     { 
      var weekToUpdate = monthToUpdate.Weeks.Single(w => w.ID == week.ID); 
      //... 

      /*So, I have a collection of weeks that I can grab, 
       but how do I know what was selected? My viewModel only has a 
       list of AllDays, not the days selected for Week[i] 
      */ 
     } 
} 

Как я могу гарантировать, что, когда я представить форму выбранные дни будут связываться недели?

+0

Какие проблемы/ошибки вы испытываете? Можем ли мы увидеть действие вашего контроллера, которое обрабатывает это сообщение формы? –

+1

Мне также будет интересно увидеть действие контроллера, которое заполняет вашу ViewModel. Интересно, что ваш класс Month уже имеет ссылку на Weeks и косвенную ссылку на Days (через Weeks), но вы добавили их в качестве дополнительных полей в ViewModel. Зачем? –

+0

Я добавил несколько методов действия psudo. Я новичок в MVC, и я придерживаюсь философии, согласно которой представление не должно запускать запросы (отправьте представление все, что нужно, в viewmodel). Если вы не думаете, что это необходимо, я могу, конечно, переключить ситуацию. Моя основная проблема (с которой я столкнулась с проблемой), заключается в том, что я не знаю, что должно быть для свойства «имя» флажка, чтобы привязка к объекту привязывала день. Я добавлю еще один небольшой параграф, объясняющий ситуацию лучше. – jbaum012

ответ

0

Похоже, что проще всего сделать это, чтобы сделать его цели для вашей формы, чтобы заполнить структуру данных типа IEnumerable<DayModel>, где DayModel определяется как:

public class DayModel 
{ 
    public int WeekId { get; set; } 
    public int DayId { get; set; } 
    public bool IsIncluded { get; set; } 
} 

Вы можете сохранить свой код Razor как это по большей части, но потом, когда дело доходит до рендеринга флажков, вы можете сделать что-то вроде этого:

@{ 
    var modelIdx = 0; 
} 

// ... 

<input type="hidden" name="days[@modelIdx].WeekId" value="@Model.Weeks[i].Id" /> 
<input type="hidden" name="days[@modelIdx].DayId" value="@Model.AllDays[d].Id" /> 
<input type="checkbox" name="days[@modelIdx].IsIncluded" value="@(Model.Weeks[i].Days.Contains(Model.AllDays[d]) ? "checked" : "")" /> 
@{ modelIdx++; } 

затем, ваше действие контроллера вы размещаете на могли бы эту подпись:

[HttpPost] 
public ActionResult Edit(IEnumerable<DayModel> days) 
{ 
    //... 
} 

Что-то, что мне помогает, - это никогда не путать модели представления, которые должны использоваться только для модели для представлений (как правило, GET-действия) и моделей не-просмотра (что мы называем обычными моделями). Избегайте, чтобы ваши действия POST пытались привязать к просмотру моделей, и это значительно упростит вашу жизнь.

Смежные вопросы