2010-03-27 53 views
8

我有一個數據庫表,它記錄了用戶被允許訪問的出版物。該表是非常簡單的 - 它只是存儲用戶ID /出版物ID對:如何使用ASP.NET MVC中的複選框創建選擇列表?

CREATE TABLE UserPublication (UserId INTEGER, PublicationID INTEGER) 

記錄的給定用戶&出版物意味着該用戶有訪問權限的存在;缺少記錄意味着無法訪問。

我想給我的管理員用戶提供一個簡單的屏幕,允許他們配置用戶可以訪問哪些出版物。我想爲每個可能的出版物顯示一個複選框,並檢查用戶當前可以訪問的複選框。然後管理員用戶可以檢查或取消檢查任何數量的出版物並提交表格。

有各種各樣的出版物類型,我想將同類型的出版物分組在一起 - 所以我確實需要控制出版物的呈現方式(我不想只有一個平面列表)。

我的視圖模型顯然需要列出所有的出版物(因爲我需要顯示所有出版物而不管當前選擇),我還需要用戶當前有權訪問的出版物列表。 (我不確定我是否最好使用單個列表,每個項目都包含發佈ID和是/否字段?)。

但是,就我所知。我真的不知道如何去綁定這個複選框。我從哪說起呢?

回答

19

的LINQ to SQL的模式您的問題看起來是這樣的:

alt text http://i39.tinypic.com/m78d1y.jpg

首先,我們需要一些幫手在我們的數據模型對象

namespace SelectProject.Models 
{ 
    public class UserPublicationSelector 
    { 
     public int UserPublicationID { get; set; } 
     public int UserID { get; set; } 
     public int PublicationID { get; set; } 
     public string PublicationName { get; set; } 
     public bool IsSelected { get; set; } 
    } 

    public class UserPublicationSelectViewModel 
    { 
     public User User { get; set; } 
     public IQueryable Selections { get; set; } 
    } 
} 

現在讓我們創建一個存儲庫,看起來像這樣:

public class Repository 
{ 
    DataContext dc = new DataContext(); 

    public User GetUser(int userID) 
    { 
     return dc.Users.FirstOrDefault(u => u.UserID == userID); 
    } 

    public IQueryable GetUserPublications(int userID) 
    { 
     return from p in dc.Publications 
       join up in dc.UserPublications on p.PublicationID equals up.PublicationID 
       where up.UserID == userID 
       orderby p.PublicationName 
       select p; 
    } 
    public IQueryable GetUserPublicationSelectors(int userID) 
    { 
     return from p in dc.Publications 
       join up in dc.UserPublications on p.PublicationID equals up.PublicationID into selected 
       from s in selected.DefaultIfEmpty() 
       orderby p.PublicationName 
       select new UserPublicationSelector 
       { 
        UserPublicationID = (int?)s.UserPublicationID ?? 0, 
        UserID = userID, 
        PublicationID = p.PublicationID, 
        PublicationName = p.PublicationName, 
        IsSelected = s.UserID != null 
       }; 
    } 

    public void UpdateUserPublications(UserPublicationSelector[] selections) 
    { 
     // Insert records for new selections... 
     foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == true)) 
     { 
      // ...where records do not yet exist in database. 
      if (selection.UserPublicationID == 0) 
      { 
       UserPublication up = new UserPublication 
       { 
        UserID = selection.UserID, 
        PublicationID = selection.PublicationID, 
       }; 
       dc.UserPublications.InsertOnSubmit(up); 
      } 
     } 
     // Delete records for unselected items... 
     foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == false)) 
     { 
      // ...where record exists in database. 
      if (selection.UserPublicationID > 0) 
      { 
       UserPublication up = dc.UserPublications.FirstOrDefault(s => s.UserPublicationID == selection.UserPublicationID); 
       if (up.UserID == selection.UserID && up.PublicationID == selection.PublicationID) 
        dc.UserPublications.DeleteOnSubmit(up); 
      } 
     } 
     // Update the database 
     dc.SubmitChanges(); 
    } 
} 

而一個控制器,看起來像這樣:

public class PublicationController : Controller 
{ 
    Repository repository = new Repository(); 

    public ActionResult Index(int id) 
    { 
     User user = repository.GetUser(id); 
     var publications = repository.GetUserPublications(id); 
     ViewData["UserName"] = user.UserName; 
     ViewData["UserID"] = user.UserID; 
     return View("Index", publications); 
    } 

    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult Select(int id) 
    { 
     var viewModel = new UserPublicationSelectViewModel() 
     { 
      User = repository.GetUser(id), 
      Selections = repository.GetUserPublicationSelectors(id) 
     }; 
     return View("Select", viewModel); 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Select(int userID, UserPublicationSelector[] selections) 
    { 
     repository.UpdateUserPublications(selections); 
     return RedirectToAction("Index", new { id = userID }); 
    } 
} 

指數視圖看起來是這樣的:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Publication>>" %> 
<%@ Import Namespace="SelectProject.Models" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    List of Selected Publications for User 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>Publications for <%= ViewData["UserName"] %></h2> 

     <table id="MyTable" style="width: 100%"> 
      <thead> 
       <tr> 
        <th> 
         Publication Name 
        </th> 
       </tr> 
      </thead> 

      <tbody> 
       <% int i = 0; 
        foreach (Publication item in Model) 
        { %> 

        <tr id="row<%= i.ToString() %>"> 
         <td> 
          <%= Html.Encode(item.PublicationName)%> 
         </td> 
        </tr> 

        <% i++; 
        } %> 
      </tbody> 
     </table> 
     <p> 
      <%= Html.ActionLink("Edit Selections", "Select", new { id = ViewData["UserID"] })%> 
     </p> 

</asp:Content> 

而且選擇視圖看起來是這樣的:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<UserPublicationSelectViewModel>" %> 
<%@ Import Namespace="SelectProject.Models" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Select Publications 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>Select Publications for <%= Model.User.UserName %></h2> 

    <% using (Html.BeginForm()) 
     { %> 

     <table id="MyTable" style="width: 100%"> 
      <thead> 
       <tr> 
        <th style="width: 50px; text-align:center"> 
         <input type="checkbox" id="SelectAll" /> 
        </th> 
        <th> 
         Publication Name 
        </th> 
       </tr> 
      </thead> 

      <tbody> 
       <% int i = 0; 
        foreach (UserPublicationSelector item in Model.Selections) 
        { %> 

        <tr id="row<%= i.ToString() %>"> 
         <td align="center" style="padding: 0 0 0 0"> 
          <%= Html.CheckBox("selections[" + i.ToString() + "].IsSelected", item.IsSelected)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].UserPublicationID", item.UserPublicationID)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].UserID", Model.User.UserID)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].PublicationID", item.PublicationID)%> 
         </td> 
         <td> 
          <%= Html.Encode(item.PublicationName)%> 
         </td> 
        </tr> 

        <% i++; 
        } %> 
      </tbody> 
     </table> 
     <p> 
      <%= Html.Hidden("userID", Model.User.UserID) %> 
      <input type="submit" value="save" /> 
     </p> 

    <% } // End Form %> 

    <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script> 

    <script type="text/javascript"> 
     // Select All Checkboxes 
     $(document).ready(function() { 
      $('#SelectAll').click(function() { 
       var newValue = this.checked; 
       $('input:checkbox').not('input:hidden').each(function() { 
        this.checked = newValue; 
       }); 
      }); 
     }); 
    </script> 

</asp:Content> 

以下是一些屏幕截圖。

alt text http://i43.tinypic.com/2yl07kw.jpg

alt text http://i44.tinypic.com/mhulua.jpg

在左上角的複選框是全選/選擇無複選框。

+0

真棒回答,謝謝。我覺得有點骯髒,就像我付了你的功課:-) – 2010-03-28 21:23:09

+0

嗨羅伯特, 優秀的深度答案!,謝謝.. 我將如何回發(保存)複選框選擇的值? – TonyP 2010-04-02 23:04:01

+1

@TonyP:該功能位於Select視圖中,具有「AcceptVerbs HttpVerbs.Post」屬性值的「選擇」控制器方法以及上述的UpdateUserPublications存儲庫方法。 – 2010-04-03 20:41:53

相關問題