2009-07-20 9 views
71

Sto utilizzando un plug-in di suggerimento jQuery per mostrare suggerimenti di guida quando l'utente alza alcuni elementi della pagina.Come eseguire una callback javascript dopo il postback di un pannello di aggiornamento?

Ho bisogno di registrare gli eventi del plugin dopo che la pagina è stata caricata usando selettori CSS.

Il problema è che sto usando un pannello di aggiornamento di ASP.NET e dopo il primo postback, i suggerimenti smettono di funzionare perché il pannello di aggiornamento sostituisce il contenuto della pagina ma non riassocia gli eventi javascript.

Ho bisogno di un modo per eseguire una callback javascript dopo che il Pannello di aggiornamento ha aggiornato il suo contenuto, così posso riassociare gli eventi javascript affinché i suggerimenti funzionino di nuovo.

C'è un modo per farlo?

risposta

163

Invece di mettere il codice jQuery all'interno di $(document).ready(), metterlo dentro

function pageLoad(sender, args) { 
    ... 
} 

pageLoad viene eseguita dopo ogni postback, sincrona o asincrona. pageLoad è un nome di funzione riservato in ASP.NET AJAX che è per questo scopo. $(document).ready() d'altra parte, viene eseguito solo una volta, quando il DOM è inizialmente pronto/caricato.

Vai a questa Overview of ASP.NET AJAX client lifecycle events

+4

Grazie per la risposta. Non sapevo che esistesse un evento pageLoad sul lato client ed è esattamente ciò di cui ho bisogno. Problema risolto. :) – tsbnunes

+0

non lo sapevo neanche, utile! tenere a mente sospetto che ciò si verificherà per tutti i UP su una pagina, avrete bisogno che il mio filtro clientid sia specifico –

+0

+1 FTW! Inoltre non sapevo che esistesse ed era esattamente quello che stavo cercando per risolvere il mio problema! Big ups @Russ Cam! – longda

12

Questo è probabilmente lontano dalla soluzione più elegante, ma la sua una soluzione comunque:

public class UpdatePanel : System.Web.UI.UpdatePanel 
{ 
    /// <summary> 
    /// Javascript to be run when the updatepanel has completed updating 
    /// </summary> 
    [Description("Javascript to be run when the updatepanel has completed updating"), 
     Category("Values"), 
     DefaultValue(null), 
     Browsable(true)] 
    public string OnUpdateCompleteClientScript 
    { 
     get 
     { 
      return (string)ViewState["OnUpdateCompleteClientScript"]; 
     } 
     set 
     { 
      ViewState["OnUpdateCompleteClientScript"] = value; 
     } 
    } 

    protected override void OnPreRender(System.EventArgs e) 
    { 
     base.OnPreRender(e); 
     if(!string.IsNullOrEmpty(this.OnUpdateCompleteClientScript)) 
      Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID, string.Concat("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args){for(var panelId in sender._updatePanelClientIDs){if(sender._updatePanelClientIDs[panelId] == '", this.ClientID, "'){", this.OnUpdateCompleteClientScript, "}}});"), true); 
    } 
} 

usare in questo modo:

<uc:UpdatePanel OnUpdateCompleteClientScript="alert('update complete');"> 
    <!-- stuff in here --> 
</uc:UpdatePanel> 

Naturalmente sarà necessario registrare il controllo personalizzato in youre webconfig o pagina per usarlo in questo modo.

Edit: anche, hai guardato jquery.live?

+1

L'utente personalizzato di aggiornamento Pannello di controllo è eccessivo per il mio problema, ma non sapevo sul metodo jquery.live e sarebbe probabilmente lavorare e risolvi il mio problema! Ma in questo caso penso che la soluzione presentata da Russ Cam sia migliore e l'ho già provata e funziona bene. Grazie per il vostro aiuto. :) – tsbnunes

+0

Ci deve essere un modo più semplice ..? –

19

Il Pageload non ha funzionato. Ho usato questo, invece:

var prm = Sys.WebForms.PageRequestManager.getInstance(); 
prm.add_pageLoaded(pageLoaded); 

function pageLoaded() { 
} 
+2

errore di riferimento non rilevato, Sys non definito –

+1

Funziona alla grande qui – Brent

+2

Se non si definisce ID sys non definito perché si sta chiamando lo script, PRIMA di lo script del gestore di script è caricato. Di solito nello , mentre il materiale scriptmanger è caricato in - Sì lo so, giusto ?! Basta spostare il tuo script in fondo alla pagina o sotto il tuo controllo e funzionerà con la multa della risposta accettata. – ppumkin

0

Se si vuole fare operazioni specifiche prima e dopo l'UpdatePanel è stato caricato, è possibile ignorare BeginPostbackRequest e EndPostbackRequest in questo modo:

var postbackControl = null; 
var updatePanels = null; 
var prm = Sys.WebForms.PageRequestManager.getInstance(); 
prm.add_beginRequest(BeginPostbackRequest); 
prm.add_endRequest(EndPostbackRequest); 

function BeginPostbackRequest(sender, args) { 
    prm._scrollPosition = null; 
    postbackControl = args.get_postBackElement(); 
    postbackControl.disabled = true; 
    updatePanels = args._updatePanelsToUpdate; 
    // do your stuff 
} 

function EndPostbackRequest(sender, args) { 
    // do your stuff 
    postbackControl.disabled = false; 
    postbackControl = null; 
    updatePanels = null; 
} 

Questo è molto utile se si vuole per elaborare solo l'HTML consegnato dal pannello di aggiornamento. Alcune operazioni richiedono più risorse e sarebbe eccessivo eseguire l'intero albero DOM su pageLoad.

evento
0

Usa pageLoaded e controllare se richiamata o postback:

var prm = Sys.WebForms.PageRequestManager.getInstance(); 
prm.add_pageLoaded(function (sender, args) { 
    if (args._panelsUpdated && args._panelsUpdated.length > 0) { 
     //callback; 
    } 
    else { 
     //postback; 
    } 
}); 
Problemi correlati