2010-09-02 26 views
28

Ho una pagina che ha qualche javascript che deve essere eseguito al caricamento della pagina. Detto javascript ha bisogno di individuare il componente lato client di un ServerControl, che fa con $ find().

Ovviamente, se emetto il mio codice direttamente sulla pagina, viene eseguito mentre la pagina viene letta e non riesce perché non viene ancora inizializzato nulla.

Se inserisco il mio codice all'interno di una funzione pageLoad(), funziona perfettamente, perché asp.net collega automaticamente un gestore onload per qualsiasi funzione denominata pageLoad(). Il problema è che non mi piace la soluzione pageLoad(), principalmente perché è un singolo nome globale. Se commetto un codice usando pageLoad(), so solo che un altro programmatore sta per copiare l'approccio, da qualche parte inappropriato, e finiremo con una pagina che include due o più funzioni diverse di PageLoad(), e il risultato sarà un mucchio di errori misteriosi che impiegheranno per sempre a rintracciare.

Quindi, ho inserito il mio codice all'interno di una funzione anonima passata a jquery $ (documento) .ready(). Ciò non riesce, poiché viene eseguito prima dell'esistenza del componente lato client di ServerControl.

Quindi, ho inserito il mio codice all'interno di una funzione anonima passata a Sys.Application.add_load(). Anche questo fallisce, perché Sys non è definito.

Quindi alla fine mi accontento di inserire il mio codice all'interno di Sys.Application.add_load(), e poi lo metto dentro una funzione chiamata da $ (document) .ready(). Funziona, ma dà quasi il bruciore di stomaco di pageLoad().

<script type="text/javascript"> 
    $(document).ready(function(){ 
     Sys.Application.add_load(function(){ 
      var component = $find(<clientid>); 
      if (component) { <do something> } 
     }); 
    }); 
</script> 

Ci deve essere un modo migliore di gestirlo.

Qualche idea?

risposta

20

Se avete il controllo del code-behind, è possibile registrare il JavaScript da eseguire all'avvio via qualcosa come:

this.Page.ClientScript.RegisterStartupScript(
    this.GetType(), 
    "StartupScript", 
    "Sys.Application.add_load(function() { functioncall(); });", 
    true); 

Finché il componente è stato caricato tramite Sys.Application.add_init() dovresti stare bene ...

+0

Sembra funzionare per noi. –

3

Credo che se si aggiunge (o si sposta) un controllo ScriptManager sopra il blocco di script, non è necessario avvolgerlo nella funzione $(document).ready() di jQuery. In questo modo a quanto pare Sys sarà disponibile come ScriptManager:

inietta la maggior parte di quel JavaScript la posizione esatta che il controllo ScriptManager è posizionato nella pagina. [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]

Tuttavia, questa soluzione può ancora dare bruciori di stomaco, come sarebbe certamente non essere evidente a tutti gli sviluppatori ignari ciò che lo ScriptManager è in realtà fornendo qui.

Un altro metodo in cui i riferimenti di script vengono aggiunti all'interno di ScriptManager (vedere "Modo migliore" trattato nell'articolo collegato sopra) non si adatta molto bene a me in quanto non sono un grande fan dell'intero approccio di ScriptManager.

5

Mi piacerebbe offrire un'alternativa per coloro che stanno provando a costruire librerie esterne e cercando di seguire il più discreto mindset javascript il più possibile all'interno di .NET.

pageLoad è un metodo eccellente per cablare automaticamente eventi AJAX che dovrebbero attivarsi su ogni caricamento della pagina (indipendentemente dal fatto che il caricamento provenga da un pulsante di navigazione di navigazione in questa pagina, un pulsante di navigazione in avanti alla pagina, un callback AJAX, uno standard caricamento della pagina, ecc.), e dal momento che non devi preoccuparti di aspettare che ScriptManager esista nel DOM, ed è chiamato in un modo che ha senso, per la maggior parte (pageLoad vs. body.onload è leggermente confondendo per i codificatori non .NET, ma per una persona .NET, ha senso che pageLoad attiva OGNI carico di pagina, anche dopo le richiamate, poiché il comportamento è identico per il lato server Page_Load). Detto questo, le tue preoccupazioni sono buone: non vuoi due istanze di pageLoad su una determinata pagina, poiché si romperà. Ecco una soluzione javascript diritta che è sicura per tutti i tuoi sviluppatori, che consente l'uso di pageLoad, non si preoccupa del DOM esistente, garantisce collisioni di codice e funziona meravigliosamente per noi.

Nella libreria javascript principale, definire Pageload, nonché una funzione di supporto:

if (!pageLoad) { var pageLoad = function (sender, args) {}; }; 
if (!mylibrarynamespace) {var mylibrarynamespace = {};}; 
if (!mylibrarynamespace.registerStartupScript) mylibrarynamespace.registerStartupScript = function (fn) { 
    /* create local pointer for added function */ 
    var f = fn; 

    /* create pointer to existing pageLoad function */ 
    var pLoad = pageLoad; 

    /* add new function pointer to pageLoad by creating new anonymous function (search Google for "javascript enclosures" for why pl and f will persist with this newly defined anonymous function) */ 
    pageLoad = function (sender, args) { 
    pLoad(sender,args); 
    f(sender, args); 
    } 
} 

Quindi, per utilizzarlo ovunque nel codice lato client, basta procedere come segue:

mylibrarynamespace.registerStartupScript(
    function (sender, args){ 
     /* do my AJAX always enabled startup code logic here*/ 
    } 
); 

Per rendere più semplice la modifica della funzionalità, è consigliabile che la funzione anonima passata chiami una funzione all'interno di quella pagina o sottoinsieme del controllo della libreria in modo che sia sufficiente modificare la dichiarazione della funzione della libreria (nel file o in fase di esecuzione in modo dinamico) su cambia come la pag eLoad per quella particolare parte del tuo sito funziona.

+0

È più idomatico in javascript scrivere le prime poche righe come questa: var pageload = pageload || funzione (mittente, args) {}; – Goyuix

0

Provare a utilizzare ScriptManager per registrare il blocco di script del client, ma assegnare un titolo univoco per ogni chiamata di funzione aggiuntiva, soprattutto se ha parametri univoci se si utilizza la stessa funzione ma con valori di parametro diversi. Se si utilizza la tecnica add_load, questa deve essere utilizzata solo quando il caricamento della pagina non è un postback, che viene chiamato solo una volta dopo l'aggiornamento della pagina o il caricamento della pagina senza un postback.

prova invece: ScriptManager.RegisterClientScriptBlock (questo, GetType(), "titolo univoco", "alert ('quick test');", true);

Problemi correlati