2012-04-10 2 views
0

J'essaye de créer un bouton sur chaque ligne d'une table de noms d'utilisateur qui bascule une fonction de verrouillage/déverrouillage contre chaque utilisateur. Je veux utiliser AJAX pour ne pas avoir à récupérer tous les utilisateurs chaque fois que la page est rechargée. Il est facile d'avoir un lien d'action AJAX dans la table, mais ensuite je me suis retrouvé coincé sur ce qu'il fallait retourner de mon contrôleur après avoir verrouillé ou déverrouillé l'utilisateur. Comme un hack je retourne une chaîne qui est le balisage html pour un nouveau lien d'action AJAX. Je théorie, je peux cliquer sur le bouton retourné dynamiquement, et continuer à basculer le verrouillage/déverrouillage. À ma grande surprise, cela a fonctionné, jusqu'à ce que je clique sur le bouton. Le bouton dynamique renvoie le balisage correct, mais sur une page vierge. Pour compliquer les choses, j'utilise une aide personnalisée pour afficher mon lien d'action. J'ai détaillé tout le code ci-dessous, si quelqu'un peut voir ce qui pourrait aller mal ou une meilleure façon de gérer cette situation, je serais reconnaissant.Renvoyer dynamiquement un lien d'action AJAX à partir d'une action du contrôleur

HTML Helper:

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)); 
    } 

Controller:

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; 
    } 

Vue:

<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> 

Répondre

0

Il pourrait y avoir plusieurs approches, telles que:

En fin de compte client, lorsque l'utilisateur clique sur un L ock/Débloquer le lien, poster une requête Ajax sur le serveur pour changer le statut de verrouillage, envoyer l'identifiant de l'utilisateur avec l'appel Ajax; Dans l'action 'Verrouiller' du serveur, l'état de verrouillage de l'utilisateur est mis à jour et l'état de l'utilisateur modifié est renvoyé en tant que données JSON au client. En fonction du résultat, modifiez le CSS du lien pour refléter le statut de verrouillage actuel. Voici l'exemple de code:

Vue:

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

CSS Exemple:

.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> 

Controller:

[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); 
    } 

Cette approche permet à votre contrôleur de rester mince et SEC. Je pense que générer une vue sous forme de chaîne à l'intérieur de l'action du contrôleur n'est pas une bonne pratique.

Une autre approche pourrait être:

Enveloppez la vue de verrouillage dans une vue partielle (par exemple UserEnableView.ascx.). La méthode d'action 'Verrouiller' doit renvoyer la vue partielle après la mise à jour de l'état de verrouillage de l'utilisateur. par exemple.

public ActionResult Lock(Guid id) 
{ 
    //...... 
    //Update user locking status. 
    //.... 
    if (Request.IsAjaxRequest()) { 
     return PartialView("UserLockView", updatedModel); 
    } 
    else{ 
     return View(updatedModel); 
    }   
} 
Questions connexes