2012-04-10 5 views
0

各ユーザーに対してロック/アンロック機能を切り替えるユーザー名の表の各行にボタンを作成しようとしています。私はAJAXを使いたいので、ページをリロードするたびにすべてのユーザーを取得する必要はありません。そのテーブルにAJAXのアクションリンクを持つことは簡単ですが、ユーザーをロックまたはロック解除した後、コントローラから返されるものについては固まっていました。ちょっとしたハックとして、新しいAJAXアクションリンクのhtmlマークアップである文字列を返します。私は理論的に返されたボタンをクリックして、ロック/アンロックをトグルし続けます。私の驚きには、実際にはうまくいきました。ダイナミックボタンは正しいマークアップを返しますが、空白のページに戻ります。さらに問題を複雑にするために、カスタムヘルパーを使用してアクションリンクを出力しています。私は以下のすべてのコードを詳しく説明しました。もし誰かが間違っているとか、このような状況に対処するためのよりよい方法を見ていただければ、私は感謝しています。コントローラアクションからAJAXアクションリンクを動的に返します。

HTMLヘルパー:

public static string ImageActionLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, object routeValues, AjaxOptions ajaxOptions) 
    { 
     var builder = new TagBuilder("img"); 
     builder.MergeAttribute("src", imageUrl); 
     builder.MergeAttribute("alt", altText); 
     var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions); 
     return link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)); 
    } 

コントローラー:

public string Lock(Guid id) 
    { 
     IUserMethods userMethods = new UserMethods(); 

     ISMPUser user = userMethods.GetUser(id, CompanyId); 
     string ajaxButtonHTML; 

     //For some reason breaking the button HTML into substrings and appending them together for readability causes the anchor tag to render incorrectly. 
     if (user.IsEnabled) 
     { 
      userMethods.AdministratorEnableAccount(CompanyId, CurrentUser.Id, user.Username, false); 
      ajaxButtonHTML = "<a class=\"row_selected\" href=\"/MMWeb/Admin/Lock/" + id.ToString() + "\" onclick=\"Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, confirm: 'Lock User?', httpMethod: 'Post', updateTargetId: 'Enable-'" + user.Id + "' });\"><img src=\"/MMWeb/Content/Images/lock.png\" alt=\"Lock\"></a>"; 
     } 
     else 
     { 
      userMethods.AdministratorEnableAccount(CompanyId, CurrentUser.Id, user.Username, true); 
      ajaxButtonHTML = "<a class=\"row_selected\" href=\"/MMWeb/Admin/Lock/" + id.ToString() + "\" onclick=\"Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, confirm: 'Lock User?', httpMethod: 'Post', updateTargetId: 'Enable-'" + user.Id + "' });\"><img src=\"/MMWeb/Content/Images/unlock.png\" alt=\"Unlock\"></a>"; 
     } 

     return ajaxButtonHTML; 
    } 

ビュー:

<td id="<%= Html.Encode("Enable-" + user.Id) %>" class="icon-column"> 
        <% if(user.IsEnabled) 
         { %> 
          <%--<img class="LockImg" alt="User Unlocked" src="<%= Url.Content("~/Content/Images/unlock.png") %>" />--%> 
          <%= Ajax.ImageActionLink(Url.Content("~/Content/Images/unlock.png"), "Lock", "Lock", new { id = user.Id.ToString() }, new AjaxOptions { Confirm = "Lock User?", HttpMethod = "Post", UpdateTargetId = "Enable-" + user.Id })%> 
        <% } 
         else 
         {%> 
          <%= Ajax.ImageActionLink(Url.Content("~/Content/Images/lock.png"), "Lock", "Lock", new { id = user.Id.ToString() }, new AjaxOptions { Confirm = "Unlock User?", HttpMethod = "Post", UpdateTargetId = "Enable-" + user.Id })%> 
        <% }%> 
       </td> 

答えて

0

のようないくつかのアプローチ、そこに持っているかもしれません:クライアント側で

を、ユーザーがLをクリックするとock/Unlockリンク、Ajaxリクエストをサーバーにポストしてロック状態を変更し、Ajaxコールでuser-Idを送信する。サーバーの「ロック」アクションの中で、ユーザーのロック状態が更新され、変更されたユーザー状況がJSONデータとしてクライアントに返されます。結果に基づいて、現在のロック状態を反映するようにリンクのCSSを変更します。ここではサンプルコードは次のとおりです。

ビュー:

<td> 
<a class='<%= (item.IsLocked ? "userLock" : "userUnlock") %>' 
    href='<%= Url.Action("ResetLock", new {id = item.Name, isLocked = item.IsLocked}) %>'> 
</a> 
</td> 

サンプルCSS:

.userLock, 
.userUnlock 
{ 
    background-image: url('/MMWeb/Content/Images/lock.png'); 
    display: block; 
    height: 16px; 
    width: 16px;       
} 
.userUnlock 
{ 
    background-image: url('/MMWeb/Content/Images/unlock.png'); 
}  

はJavaScript:

<script type="text/javascript"> 
$(function() { 

    $('a.userLock, a.userUnlock').click(function (e) { 

     e.preventDefault() 
     var $this = $(this); 

     $.ajax({ 
      url: $this.attr('href'), 
      type: "POST", 
      dataType: "json", 

      success: function (result, textStatus, jqXHR) { 
       if (result.status == "Succeed") { 
        if (result.IsLocked == true) {         
         $this.removeClass('userUnlock').addClass('userLock'); 
        } 
        else {         
         $this.removeClass('userLock').addClass('userUnlock'); 
        } 
       } 
      }, 
      error: function() { 
       alert('Failed to reset lock.'); 
      } 
     }); 
    }); 
}); 
</script> 

コントローラー:

[HttpPost] 
    public ActionResult ResetLock(Guid id) 
    { 
     //...... 
     //Update user locking status. 
     //user.IsEnabled = !user.IsEnabled; 
     //...... 

     var updatedModel = new { 
      status = "Succeed", 
      IsLocked = user.IsEnabled 
     }; 

     return Json(updatedModel); 
    } 

この方法は、コントローラの動作を薄くしてDRYに保ちます。 私は、コントローラーのアクション内で文字列としてビューを生成するのは良い方法ではないと思います。

別のアプローチは、かもしれない:

ラップ部分図(例えばUserEnableView.ascx。)でロック図。 'ロック'アクションメソッドは、ユーザーのロック状態を更新した後、部分ビューを返す必要があります。例えば

public ActionResult Lock(Guid id) 
{ 
    //...... 
    //Update user locking status. 
    //.... 
    if (Request.IsAjaxRequest()) { 
     return PartialView("UserLockView", updatedModel); 
    } 
    else{ 
     return View(updatedModel); 
    }   
} 
関連する問題