2016-03-01 42 views
1

不知道爲什麼我放棄了投票,但是我會在做一些研究和測試之後重新編寫我的問題。這是我用來學習MVC/EF/Repository/Bootstrap等的一個輔助項目。我每週只在這裏花幾個小時在這裏工作。我應該使用ViewBag將列表傳遞給View嗎?

基本原題:

我知道我真的應該使用一個ViewModel列表<>來傳遞數據的看法,但我不知道它是如何或是否符合我的要求。

我想要做的是得到一個用戶列表顯示在一個表中,每個表中都有一個複選框。在該表格上方,我想要列出可以分配到的組的列表。您從DropDownList(DDL)中選擇部分,然後檢查您想要分配給誰。這是我想要分配爲列表並傳遞給視圖的組/部分。

所以,我有一個列表的ViewModel,我正在使用一個存儲庫來填充虛擬機。我不知道該怎麼做,到底是在哪裏/何時向每個虛擬機對象填充該列表,即使我做了也有50個用戶,我不想讓50次訪問數據庫來獲取相同的信息這就是爲什麼我認爲在這種情況下使用ViewBag將該組列表傳遞給View可能是合理的。另一方面,我想了解如何在虛擬機中正確填充該列表以供將來編碼。

更新問題/代碼:

所以,更多的研究和下面的一些建議後,我現在已經得到了下面的代碼。我仍然不確定如何正確填充我的ViewModel中的巡視以便在View中填充DDL。

目前,我已經看到顯示錶格與複選框。現在我回過頭來研究如何獲取值來填充DDL,然後我必須發佈到控制器,循環查找檢查行並更新數據庫。在我的情況下,每個成員記錄默認爲PatrolId = 0,並且此頁面應允許我將PatrolId更新爲DDL中的值。

PatrolMemberViewModel中的Patrols屬性應該是我從數據庫表中取出的約5條記錄的列表,而不是DDL中的硬編碼。

視圖模型:

public class PatrolViewModel 
    { 
     public int PatrolId { get; set; } 
     public string PatrolName { get; set; } 
    } 

    public class PatrolMemberViewModel 
    { 
     [Key] 
     public int MemberId { get; set; } 

     public int PatrolId { get; set; } 


     [Display(Name = "First Name")] 
     public string FirstName { get; set; } 


     [Display(Name = "Last Name")] 
     public string LastName { get; set; } 


     [Display(Name = "Phone")] 
     public string PhonePrimary { get; set; } 


     [Display(Name = "Email")] 
     public string EmailPrimary { get; set; } 

     public bool IsSelected { get; set; } 

     public PatrolViewModel Patrols { get; set; } 

    } 

控制器:

public ViewResult Unassigned() 
     { 
      try 
      { 
       IEnumerable<PatrolMemberViewModel> model = repository.SelectAllUnassigned(); 
       return View(model); 
      } 
      catch (Exception) 
      { 
       ModelState.AddModelError(string.Empty, "Error retrieving the record."); 
       return View(); 
      } 
     } 

庫:

public IEnumerable<PatrolMemberViewModel> SelectAllUnassigned() 
     { 
      using (DataContext db = new DataContext()) 
      { 
       var results = (from p in db.Person 
           where p.IsActive == true 
           && p.IsScout == true 
           && p.PatrolId == 0 
           select new PatrolMemberViewModel 
           { 
            MemberId = p.PID, 
            FirstName = p.FirstName ?? string.Empty, 
            LastName = p.LastName ?? string.Empty, 
            EmailPrimary = p.EmailPrimary ?? string.Empty, 
            PhonePrimary = p.PhonePrimary ?? string.Empty, 
            PatrolId = p.PatrolId, 
            IsSelected = false 
           } 
           ).OrderBy(o => o.LastName).ThenBy(o => o.FirstName).ToList(); 

       return results; 
      } 
     } 

查看:

@model IList<ProjectName.ViewModels.PatrolMemberViewModel> 

@{ 
    ViewBag.Title = "Unassigned"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Patrols</h2> 


@using (Html.BeginForm("Update", "Patrol", FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(false, "", new { @class = "alert alert-danger" }) 

    <table class="table table-bordered table-striped table-hover table-condensed tbackground"> 
     <tr> 
      <th class="text-center"> 

      </th> 
      <th class="text-center"> 
       First Name 
      </th> 
      <th class="text-center"> 
       Last Name 
      </th> 
      <th class="text-center"> 
       Email 
      </th> 
      <th class="text-center"> 
       Phone 
      </th> 
     </tr> 


     @for (var i = 0; i < Model.Count(); i++) 
     { 
     <tr> 
      <td class="text-center"> 
       @Html.CheckBoxFor(m => m[i].IsSelected) 
      </td> 
      <td> 
       @Html.DisplayFor(m => m[i].FirstName) 
      </td> 
      <td> 
       @Html.DisplayFor(m => m[i].LastName) 
      </td> 
      <td> 
       <a href="mailto:@Model[i].EmailPrimary">@Model[i].EmailPrimary</a> 
      </td> 
      <td class="text-center"> 
       @Html.DisplayFor(m => m[i].PhonePrimary) 
      </td> 
     </tr> 
     } 

    </table> 

    <div class="control-wrapper"> 
     <input type="submit" id="btnSubmit" value="Assign" class="btn btn-success" /> 
    </div> 
} 
<p>&nbsp;</p> 
+2

對數據庫進行50次調用與ViewBag vs ViewModel解決方案無關。這是關於你如何查詢.http://stackoverflow.com/questions/33921262/is-deferred-execution-in-asp-net-mvc-view-a-very-bad-thing/33921573#33921573 – Shyju

+0

@Shyju ...你能看看我在我的問題中發佈的更新,看看你能告訴我做錯了什麼嗎?感謝... – Caverman

+0

將您的_ users_和_list_ Groups列表關聯到您所顯示的代碼(這與'MemberSectionViewModel'和'Sections'和'PatrolViewModel'和'MemberPatrolViewModel'有什麼關係? –

回答

1

首先創建視圖模型來表示要在視圖中顯示/編輯的內容。您可以使用您的PatrolMemberViewModel,但可以刪除[Key]屬性和int PatrolIdPatrolViewModel Patrols屬性。

然後創建父視圖模型

public class AssignPatrolViewModel 
{ 
    [Display(Name = "Patrol")] 
    [Required(ErrorMessage = "Please select a patrol")] 
    public int? SelectedPatrol { get; set; } 
    public IEnumerable<SelectListItem> PatrolList { get; set; } 
    public List<PatrolMemberViewModel> Members { get; set; } 
} 

,你會得到一種方法是

public ViewResult Unassigned() 
{ 
    var model = new AssignPatrolViewModel 
    { 
     PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName"), // modify to suit 
     Members = repository.SelectAllUnassigned().ToList() 
    }; 
    return View(model); 
} 

,並在POST方法的觀點

@model AssignPatrolViewModel 
.... 
@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(m => m.SelectedPatrol) 
    @Html.DropDownListFor(m => m.SelectedPatrol, Model.PatrolList, "Please select") 
    @Html.ValidationMessageFor(m => m.SelectedPatrol) 
    <table> 
     .... // thead elements 
     <tbody> 
      @for(int i = 0; i < Model.Members.Count; i++) 
      { 
       <tr> 
        <td> 
         @Html.CheckBoxFor(m => m.Members[i].IsSelected) 
         @Html.HiddenFor(m => m.Members[i].MemberId) 
         // add other hidden inputs for properties you want to post 
        </td> 
        <td>@Html.DisplayFor(m => m.Members[i].FirstName)</td> 
        .... 
       </tr> 
      } 
     </tbody> 
    </table> 
    <input type="submit" value="Assign" class="btn btn-success" /> 
} 

然後

[HttpPost] 
public ViewResult Unassigned(AssignPatrolViewModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     model.PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName"); 
     return View(model); 
    } 
    // Get selected ID's 
    IEnumerable<int> selected = model.Members.Where(m => m.IsSelected).Select(m => m.MemberId); 
    // Get matching data models 
    var members = db.Person.Where(p => selected.Contains(p.PID)); // modify to suit 
    // loop each each member, update its PatrolId to the value of model.SelectedPatrol 
    // save and redirect 
} 
+0

非常感謝花時間寫這個。在過去的幾天裏,我一直在努力解決這個問題,並且接近你的所作所爲,但是這種挑戰有助於彌補差距並使之發揮作用。我還沒有完成POST,但接下來我會用你的例子。 – Caverman

+0

我有一點時間開始研究POST的這一部分。使用你的示例我能夠得到選定的成員和他們的對象,但我不明白我將如何從下拉列表中選擇PatrolId。我會盡力搜索那篇文章,看看我能想出什麼。 – Caverman

+0

所選的PatrolID值在'model.SelectedPatrol'中(參見上一段代碼片段末尾的註釋,例如,可以使用'foreach(成員中的var成員){member.PatrolID = model.SelectedPatrol;。 ...};' –

0

您可以爲您的視圖模型創建一個新類,將用戶列表和部分列表作爲其中的屬性。有些人似乎喜歡這種方法。

但我認爲你使用ViewBag來傳遞部分列表是完全有效的。我一直這樣做DDL這樣的。

相關問題