2012-09-12 98 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; } 
} 

...和實例視圖模型:

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

編輯動作/視圖的目的是使用戶編輯月,分配給該月的星期,以及從某個月的幾周添加和刪除日期。一個看法可能有幫助。

@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的新手,我遵循一種理念,即視圖不應該運行查詢(在視圖模型中發送視圖所需的所有內容)。如果你不認爲這是必要的,那麼我當然可以改變事物。我的主要問題(我有困難闡述)是,我不知道複選框的「名稱」屬性需要爲模型聯編程序分配一天。我會再增加一小段來更好地解釋這種情況。 – jbaum012

回答

0

看起來最容易做的事情是讓一個目標表單來填充型IEnumerable<DayModel>,其中DayModel被定義爲一個數據結構:

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

你可以讓你的剃刀代碼因爲是大部分,但隨後當談到渲染複選框,你可以做這樣的事情:

@{ 
    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動作試圖綁定到視圖模型,這將大大簡化你的生活。