2009-02-08 5 views
1

J'ai un peu un problème avec les contrôles utilisateur. Fondamentalement ce que je veux accomplir est le suivant:Ajax.BeginForm, contrôles utilisateur et mise à jour de quelque chose

  1. J'ai une vue pour éditer une facture.
  2. Dans ce point de vue j'ai une usercontrol avec une liste d'éléments de facture
  3. J'ai aussi un div qui est activé avec jQuery pour ajouter un nouvel élément de la facture
  4. Lorsque j'ajoute l'élément de la facture que je veux rafraîchir juste la contrôle de l'utilisateur avec la liste des éléments

Comment ferais-je cela sans hacks? Quelque chose que je pensais était la suivante:

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] 
public ActionResult Create(InvoiceLine line) 
{ 
if (Request.IsAjaxRequest()) 
{ 
    if (!ModelState.IsValid) 
    { 
     return PartialView("CreateLineControl", product); 
    } 
}   
return PartialView("DisplayLinesControl", product); 
} 

Répondre

0

D'abord, vous appelleriez une page ASPX w/jQuery (nous utiliserons un gestionnaire http que nous la carte dans le web.config ci-dessous, plus tard)

l'idée de base est que nous voulons que le côté serveur pour rendre le contrôle de l'utilisateur comme xhtml et vidage de cette « mise à jour » le balisage de retour dans le DOM dans notre méthode de succès (côté client)

$.ajax({ 
    type: "GET", 
    url: "UserDetails.aspx?id=" + id, 
    dataType: "html", 
    error: function(XMLHttpRequest, textStatus, errorThrown) 
    { 
     alert(XMLHttpRequest.responseText); 
    }, 
    success: function(xhtml) 
    { 
     var container = document.createElement('div'); 

     container.innerHTML = xhtml; 

     document.getElementById('someElement').appendChild(container); 
    } 
}); 

la technique ci-dessous est ce que je utilisé pour tirer parti d'un contrôle utilisateur via le HttpHandler pour réutiliser le le contrôle pour les ajax et le travail .net

Le dessous a été fait w/.NET 1.1 (mais je suis sûr que vous pouvez le faire dans .NET 2.0+) la classe ci-dessous implémente IHttpHandler, et le vrai travail est dans le processus demande sous comme vous pouvez voir ci-dessous

Le seul problème que j'ai eu avec cela à ce moment était que les contrôles asp.net ne rendrait pas sans étiquette de forme dans le contrôle de l'utilisateur donc j'ai utilisé html normal et tout était bon

Public Class AJAXHandler 

    Implements IHttpHandler 

    Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable 
     Get 
      Return False 
     End Get 
    End Property 

    Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest 
     Dim Request As System.Web.HttpRequest = context.Request 
     Dim path As String = Request.ApplicationPath 
     Dim newHtml As String 
     Dim pg As New System.Web.UI.Page 

     context.Response.Cache.SetCacheability(HttpCacheability.NoCache) 
     context.Response.ContentType = "text/html" 

           Dim uc As New UserDetail 
           uc = CType(pg.UserControl(path + "/Controls/UserDetail.ascx"), UserDetail) 
           Dim sb As New System.Text.StringBuilder 
           Dim sw As New System.IO.StringWriter(sb) 
           Dim htmlTW As New HtmlTextWriter(sw) 

           uc.LoadPage(custid, CType(pro, Integer)) 
           uc.RenderControl(htmlTW) 
           context.Response.Write(sb.ToString()) 
           context.Response.End() 

    End Sub 


End Class 

Et enfin dans votre web.config vous devez définir le gestionnaire et la carte au chemin de ASPX que vous avez indiqué dans votre appel ajax

<system.web> 
    <httpHandlers> 
     <add verb="*" path="UserDetails.aspx" type="project.AJAXHandler, project" /> 
    </httpHandlers> 
    </system.web> 

Maintenant, vous pouvez appeler le contrôle utilisateur avec UserDetails.aspx et rendre le contrôle de l'utilisateur comme html. Puis, après vous rendez cela, il retournera html (après Response.End est appelé)

puis en javascript vous pouvez trouver l'élément DOM parent à votre contrôle utilisateur, retirez-le et ajoutez ou innerHTML ce nouveau html

Mise à jour

Ci-dessus est la solution que j'ai utilisé avec des formulaires Web, mais avec MVC, le résultat ci-dessous produira le même résultat avec beaucoup moins de travail.

La fonction jQuery serait le même, mais sur le côté serveur vous suffit de créer une nouvelle action du contrôleur + PartialView w/le balisage que vous vouliez (essentiellement un contrôle utilisateur)

Function Edit(ByVal id As Integer) As ActionResult 
    Dim User As User = UserService.GetUserById(id) 

    Return PartialView("User", User) 
End Function 

maintenant dans mon ascx I il suffit de rendre le code HTML et c'est ce qui est renvoyé au navigateur pour le conteneur.travaux de innerHTML (encore une fois le code côté client est le même pour les deux MVC et Webforms dans ce scénario)

<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl(Of User)" %> 
<% Dim User As User = DirectCast(Model, User)%> 
<div id="innerDetail"> 
    <label for='username'>Username</label> 
    <input type="text" id='username' name='username' value="<%= User.Username %>" /><br /> 

    <a id='lnkUpdate' href='/Application/User.aspx/Edit/<%= User.ID %>' onclick='UpdateUser(this); return false;'>Update User Information</a> 
    <span id='lblUpdateStatus' style='display: inline;'></span> 
    </div> 
</div> 

La raison pour laquelle cela fonctionne avec beaucoup moins de code dans MVC est que nous ne devons pas travailler autour du cycle de vie de la page cela est requis avec un fichier aspx normal dans les formulaires Web.

+0

C'est une très bonne solution. Je n'ai pas encore eu le temps de jouer avec ça. Je reviendrai à vous à ce sujet. Le temps vole juste :) – mhenrixon

+0

Je crois que vous n'avez pas besoin d'un gestionnaire pour cela parce que les méthodes de contrôleur sont publiques et accessibles via les URL appropriées. Mais c'est une bonne direction. :) –

+0

Cela devra faire :) – mhenrixon

Questions connexes