Annulation d'une publication (postback) asynchrone
Mise à jour : novembre 2007
Les publications asynchrones sont implémentées dans ASP.NET en utilisant des contrôles serveur Web UpdatePanel NET dans la page. Le contrôle UpdatePanel supprime la nécessité d'actualiser la page entière lors de chaque publication, ce qui améliore l'expérience de l'utilisateur. Dans le navigateur, la classe Sys.WebForms.PageRequestManager, de Microsoft AJAX Library, gère les événements lors du cycle de vie de la page client pour les publications asynchrones. Vous pouvez personnaliser la manière dont les publications asynchrones se produisent en gérant les événements déclenchés par la classe PageRequestManager.
Dans ce didacticiel vous utiliserez l'événement initializeRequest de la classe PageRequestManager pour annuler la publication asynchrone en cours d'exécution.
Pour plus d'informations sur la séquence d'événements déclenchée dans la classe PageRequestManager, consultez Utilisation d'événements PageRequestManager.
Composants requis
Pour implémenter les procédures dans votre propre environnement de développement, vous avez besoin des éléments suivants :
Microsoft Visual Studio 2005 ou Microsoft Visual Web Developer Express.
Un site Web ASP.NET AJAX.
Création d'un script annulant des publications
Vous commencerez par créer le code ECMAScript (JavaScript) qui gère la publication asynchrone dans le navigateur.
Pour créer le code Javascript annulant une publication
Dans le site Web ASP.NET, ajoutez un nouveau fichier JScript et nommez-le CancelPostback.js.
Ajoutez le script suivant au fichier :
var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus); } function CheckStatus(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') { prm.abortPostBack(); } else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { args.set_cancel(true); ActivateAlertDiv('visible', 'Still working on previous request.'); } else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { ActivateAlertDiv('visible', 'Retrieving headlines.'); } } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus); } function CheckStatus(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') { prm.abortPostBack(); } else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { args.set_cancel(true); ActivateAlertDiv('visible', 'Still working on previous request.'); } else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { ActivateAlertDiv('visible', 'Retrieving headlines.'); } } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
Le script effectue les tâches suivantes :
Définit un gestionnaire pour l'événement load de la classe Sys.Application. Ce gestionnaire enregistre ensuite un gestionnaire nommé CheckStatus pour l'événement initializeRequest de la classe PageRequestManager.
Définit le gestionnaire CheckStatus pour vérifier si une publication asynchrone est en cours d'exécution, et pour déterminer le nom de l'élément qui a provoqué la publication.
Définit une fonction ActivateAlertDiv qui fait basculer la visibilité d'un élément <div> servant à afficher des messages.
Utilisation du Script avec un contrôle UpdatePanel
Dans cette procédure vous utiliserez le script que vous avez créé dans une page contenant un contrôle UpdatePanel. Le script annule la publication si l'utilisateur clique sur un lien pendant que la publication asynchrone est en cours.
Pour créer une page sur laquelle les utilisateurs peuvent annuler une publication
Créez une nouvelle page Web ASP.NET composée d'un fichier unique nommé Default.aspx et basculez en mode Design.
Sous l'onglet Extensions AJAX de la boîte à outils, double-cliquez sur le contrôle ScriptManager pour l'ajouter à la page.
Dans la boîte à outils, double-cliquez sur le contrôle UpdatePanel pour l'ajouter à la page.
Basculez en mode Source et ajoutez les règles de style suivantes à un bloc <style> dans l'élément <head> de la page :
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style>
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style>
Les règles de style définissent la hauteur et la largeur de l'élément <div> restitué par le contrôle UpdatePanel. Les règles définissent également l'apparence de l'élément <div> imbriqué qui affiche un message de progression.
Ajoutez le balisage suivant dans l'élément <ContentTemplate> de l'élément <asp:UpdatePanel> :
<asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton>
<asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton>
Le balisage effectue les tâches suivantes :
Définit un contrôle DataList dont les éléments sont liés à un champ Value, qui sera défini ultérieurement dans cette procédure comme objet SortedList.
Définit un contrôle Button qui génère une publication asynchrone.
Définit un élément <div> qui sera utilisé pour afficher un message pendant une publication asynchrone. L'élément <div> contient également un contrôle LinkButton qui permet à la publication d'être annulée.
Dans l'élément <script >, ajoutez le code serveur suivant comme gestionnaire d'événements Click, prévu pour le bouton Actualiser dans le contrôle UpdatePanel.
Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(2000) HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End Sub
protected void NewsClick_Handler(object sender, EventArgs e) { System.Threading.Thread.Sleep(2000); HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); }
Le code utilise la liaison de données pour lire et afficher une liste de titres dans le contrôle DataList.
Remarque : Le gestionnaire de l'événement Click introduit volontairement un délai pour ce didacticiel. Dans la pratique, vous n'introduiriez pas de délai. Au lieu de cela, le délai aurait pour cause le trafic sur le serveur ou le temps de traitement d'un code serveur plus long que d'habitude, pour une requête de base de données par exemple.
Au sein de l'élément <script>, ajoutez le code suivant pour l'événement Load de la page :
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If Not (IsPostBack) Then HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End If End Sub
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } }
Le code vérifie si la requête courante est une publication. Si la requête n'est pas une publication, le contrôle DataList est lié à une liste de titres. (Lors des publications asynchrones, la liaison de données se produit dans la méthode NewClick_Handler que vous avez créée durant l'étape précédente.)
Au sein de l'élément <script>, ajoutez le code suivant permettant de générer les titres :
' Helper method to simulate news headline fetch. Private Function GetHeadlines() As SortedList Dim headlines As New SortedList() headlines.Add(1, "This is headline 1.") headlines.Add(2, "This is headline 2.") headlines.Add(3, "This is headline 3.") headlines.Add(4, "This is headline 4.") headlines.Add(5, "This is headline 5.") headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")") Return headlines End Function
// Helper method to simulate news headline fetch. private SortedList GetHeadlines() { SortedList headlines = new SortedList(); headlines.Add(1, "This is headline 1."); headlines.Add(2, "This is headline 2."); headlines.Add(3, "This is headline 3."); headlines.Add(4, "This is headline 4."); headlines.Add(5, "This is headline 5."); headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")"); return headlines; }
Les titres dans ce didacticiel sont créés en tant que liste statique. Dans une application réelle, ils seraient générés dynamiquement.
Basculez en mode Design et assurez-vous que la page ressemble à l'illustration suivante.
Sélectionnez le contrôle ScriptManager.
Dans la fenêtre Propriétés, sélectionnez la propriété Scripts et cliquez sur le bouton de sélection (…) pour afficher la boîte de dialogue Éditeur de collections ScriptReference.
Cliquez sur Ajouter pour ajouter une référence de script.
Affectez la valeur CancelPostback.js à la propriété Path de la référence de script, c'est le fichier JavaScript que vous avez créé précédemment.
L'ajout d'une référence de script à l'aide de la collection Scripts du ScriptManager assure le chargement du script après que le chargement de Microsoft AJAX Library.
Cliquez sur OK pour fermer la boîte de dialogue Éditeur de collections ScriptReference.
Enregistrez vos modifications et appuyez sur CTRL+F5 pour afficher la page dans un navigateur.
Cliquez sur le bouton Actualiser et que le panneau soit actualisé.
Un message est affiché avec une option permettant d'annuler la publication.
Cliquez de nouveau sur le bouton Actualiser et, après que le message s'affiche, cliquez une nouvelle fois sur le bouton Actualiser puis attendez que le panneau soit actualisé.
Le texte du message change pour indiquer que l'actualisation précédente est encore en cours. La seconde actualisation est ignorée.
Cliquez à nouveau sur encore le bouton Actualiser et, lorsque le message s'affiche, cliquez sur le lien Annuler pour annuler la publication.
Cette fois-ci, la durée affichée dans le contrôle UpdatePanel ne change pas, parce que la publication asynchrone a été annulée.
<%@ Page Language="VB" %> <%@ Import Namespace="System.Collections.Generic" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(2000) HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If Not (IsPostBack) Then HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End If End Sub ' Helper method to simulate news headline fetch. Private Function GetHeadlines() As SortedList Dim headlines As New SortedList() headlines.Add(1, "This is headline 1.") headlines.Add(2, "This is headline 2.") headlines.Add(3, "This is headline 3.") headlines.Add(4, "This is headline 4.") headlines.Add(5, "This is headline 5.") headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")") Return headlines End Function </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>Canceling Postback Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style> </head> <body> <form id="form1" > <div > <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="CancelPostback.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="Server" > <ContentTemplate> <asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
<%@ Page Language="C#" %> <%@ Import Namespace="System.Collections.Generic" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void NewsClick_Handler(object sender, EventArgs e) { System.Threading.Thread.Sleep(2000); HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } } // Helper method to simulate news headline fetch. private SortedList GetHeadlines() { SortedList headlines = new SortedList(); headlines.Add(1, "This is headline 1."); headlines.Add(2, "This is headline 2."); headlines.Add(3, "This is headline 3."); headlines.Add(4, "This is headline 4."); headlines.Add(5, "This is headline 5."); headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")"); return headlines; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Canceling Postback Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style> </head> <body> <form id="form1" > <div > <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="CancelPostback.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="Server" > <ContentTemplate> <asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
Récapitulatif
Ce didacticiel indique comment écrire un code Javascript qui annule une publication asynchrone. Le script fournit un gestionnaire pour l'événement initializeRequest de la classe PageRequestManager. Dans l'événement initializeRequest, vous pouvez déterminer l'élément qui a provoqué la publication et si une publication est déjà en cours. Vous ensuite pouvez prendre les mesures qui s'imposent. Dans le didacticiel, le code affiche un élément <div> comportant un bouton d'annulation.
Pour afficher automatiquement l'état du contrôle UpdatePanel, vous pouvez utiliser le contrôle UpdateProgress. Pour plus d'informations, consultez Introduction au contrôle UpdateProgress.
Voir aussi
Tâches
Programmation de contrôles UpdateProgress dans un script client
Concepts
Utilisation d'événements PageRequestManager
Référence
Sys.WebForms.PageRequestManager, classe
initializeRequest, événement de Sys.WebForms.PageRequestManager