2011-03-09 90 views
2

我被困在ViewModel綁定和刷新場景中。ASP.NET MVC 3 - ViewModel&Refresh - 問題

場景: 作爲管理員我想要創建用戶帳戶並基於從DropDownList中選擇的角色刷新FORM以通過複選框選擇與角色相關的特定訪問(布爾)。

因此,用戶可以擁有一個具有默認訪問權限列表的角色,當他創建Account時,可以由Admin修改該角色。

我的視圖模型:

public class CreateViewModel 
{ 
    public User User { get; set; } 
    public IEnumerable<Role> Roles { get; set; } 
    public IEnumerable<RoleAccess> RoleAcceses { get; set; } 
    public Role SelectedRole { get; set; } 


    public void Refresh() 
    { 
     User.UserAccesses.Clear(); 
     foreach (var item in RoleAcceses.Where(x => x.RoleId == SelectedRole.Id)) 
     { 
      User.UserAccesses.Add(new UserAccess { UserId = User.Id, Access = item.Access, AccessId = item.AccessId, Value = item.Value }); 
     } 
    } 
} 

正如你可以看到上面的代碼我有RoleAccess收集與特定角色的默認值。 Refresh方法會清除實際的UserAccess集合並將其重新填充爲SelectedRole。

我的問題是:

  1. 是否有可能做到這一點沒有jQuery的?你有什麼意見?
  2. 如果可以刷新沒有jQuery的FORM如何發佈它,而不會丟失管理員輸入的綁定值? 在這裏,我不能添加其他@BeginForm,因爲我會失去實際的數據上下文嗎?
  3. 如果jQuery只是解決方案如何編寫Controller Action來檢查jQuery Filtering?
  4. jQuery函數應該如何替換綁定到ViewModel複選框?

我courrent控制器操作:

public class AccountController : Controller 
{ 
    IAccountService accountService; 

    public AccountController() 
    { 
     accountService = new AccountService(); 
    } 

    [HttpGet] 
    public ActionResult Create(int role = 1) 
    { 
     IEnumerable<RoleAccess> roleAccesses = null; 
     IEnumerable<Role> roles = null; 

     roleAccesses = accountService.GetRoleAcgesses(); 
     roles = accountService.GetRoles(); 

     var createViewModel = new CreateViewModel(); 
     createViewModel.RoleAcceses = accountService.GetRoleAccesses(); 
     createViewModel.Roles = accountService.GetRoles(); 
     createViewModel.SelectedRole = createViewModel.Roles.FirstOrDefault(x => x.Id == role); 
     createViewModel.Refresh(); 

     return View(createViewModel); 
    } 

    public ActionResult Refresh(int role) 
    { 
     return RedirectToAction("Create", "Account", new { role }); 
    } 

    [HttpPost] 
    public ActionResult Create([Bind(Prefix = "User")] Models.User user, FormCollection formsCollection) 
    { 
     var viewModel = new CreateViewModel(); 
     UpdateModel<CreateViewModel>(viewModel, new[] { "User.Login", "User.Password", "User.FirstName", "User.LastName" }); 

     viewModel.User.RoleId = Convert.ToInt32(formsCollection["Role"]); 

     if (ModelState.IsValid) 
     { 
      bool result = accountService.CreateAccount(viewModel.User); 

      if (!result) 
      { 
       // SEND INFO ABOUT FAILURE 
      } 
      else 
      { 
       return RedirectToAction("list"); 
      } 
     } 

     return View(); 
    } 

    [HttpGet] 
    public ActionResult List() 
    { 
     var accounts = accountService.GetAccounts(); 
     var viewModel = new ListViewModel() { Accounts = accounts }; 
     return View(viewModel); 
    } 
} 

筆者認爲:

@model VDOT.Web.AccountViewModels.CreateViewModel 
@{ 
    ViewBag.Title = "Create"; 
} 
<h2>Create</h2> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm("create", "account")) 
{ 
@Html.AntiForgeryToken() 
@Html.ValidationSummary(true) 
<fieldset> 
    <legend>CreateViewModel</legend> 
    <fieldset> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.User.Login) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.User.Login) 
      @Html.ValidationMessageFor(model => model.User.Login) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.User.Password) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.User.Password) 
      @Html.ValidationMessageFor(model => model.User.Password) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.User.FirstName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.User.FirstName) 
      @Html.ValidationMessageFor(model => model.User.FirstName) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.User.LastName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.User.LastName) 
      @Html.ValidationMessageFor(model => model.User.LastName) 
     </div> 
     <div class="editor-field"> 
      <select id="paging" onchange="location.href=this.value"> 
       @foreach (var item in Model.Roles) 
       { 
        <option value="@Url.Action("create", "account", new { role = item.Id })"> 
         @item.Name 
        </option> 
       } 
      </select> 
     </div> 
     <div class="editor-field"> 
      @foreach (var item in Model.User.UserAccesses) 
      { 
       @Html.CheckBox(item.Access.Name, item.Value); 
       <br /> 
      } 
     </div> 
    </fieldset> 
</fieldset> 
<fieldset> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

感謝您的幫助!

+1

在knockout.js有一個lool你可以使用客戶端side.scripting ... – Haroon 2011-03-26 21:24:22

+0

這太酷了...一個問題如何將這與控制器操作的ajax請求集成? – 2011-04-07 18:52:22

+0

看看史蒂夫桑德森博客或淘汰賽網站本身,應該有很多將它與ajax集成的例子,一旦你進入它就很簡單了,注意:根據我的理解你會使用JSON很多,這隨着JavaScript處理得非常好,使生活更輕鬆。鏈接:http://knockoutjs.com/examples/ – Haroon 2011-04-08 08:19:20

回答

1

我認爲你正在尋找一種方法來綁定你的用戶訪問集合到你的用戶視圖模型。有了這個功能,您的完整模型將在回發後保持不變,從而允許您在不使用腳本的情況下實現所需的任何功能(儘管如果可用的話,您可以使用jQuery來增強「更流暢」功能的頁面)。

Steven Sanderson's blog, here上提供了一個創建模型列表屬性綁定的好方法。

+0

不錯。如果這可能與Haroon提到的knockout.js有關,我們將創建類似於WPF/Silverlight Databinding的東西:-) – 2011-04-07 18:54:07