Non è possibile ottenere ScriptManager.RegisterStartupScript in WebControl nidificata in un UpdatePanel per lavoro

StackOverflow https://stackoverflow.com/questions/802506

Domanda

Sto avendo quello che credo dovrebbe essere una cosa abbastanza semplice problema, ma per la vita di me non riesco a vedere il mio problema.Il problema è correlato a ScriptManager.RegisterStartupScript, qualcosa che ho usato molte volte prima.

Lo scenario che ho è che ho un controllo web personalizzato che è stato inserito in una pagina.Il controllo (e uno o due altri) sono nidificati all'interno di un UpdatePanel.Sono inseriti sulla pagina su un Segnaposto:

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

Questo è l'unico pannello di aggiornamento della pagina.

Il controllo richiede un po ' di iniziale di javascript per funzionare correttamente.Le chiamate di controllo:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

e ho provato anche:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

Il problema è che lo script viene eseguito correttamente quando la pagina viene visualizzata per la prima volta, ma non eseguire nuovamente dopo un parziale di postback.Ho provato le seguenti:

  1. Chiamata RegisterStartupScript da CreateChildControls
  2. Chiamata RegisterStartupScript da OnLoad / OnPreRender
  3. Utilizzando diverse combinazioni di parametri per i primi due parametri (nell'esempio sopra, il Controllo di Pagina e il Tipo di GetType(), ma ho provato con il controllo di sé, ecc).
  4. Ho provato con persistente e nuovo id (non che credo che questo dovrebbe avere un impatto maggiore in entrambi i modi).
  5. Ho usato un paio di punti di interruzione e quindi hanno verificato che il Registro viene chiamato correttamente.

L'unica cosa che non ho provato è utilizzando l'UpdatePanel se stesso come il Controllo e il Tipo, come non credo che il controllo dovrebbe essere consapevoli del pannello di aggiornamento (e in ogni caso non sembra essere un buon modo per ottenere il pannello di aggiornamento?).

Chiunque può vedere quello che potrebbe essere sbagliato in precedenza?

Grazie :)


Beh, per rispondere alla query di cui sopra - non sembra come se il segnaposto in qualche modo scombina ScriptManager.RegisterStartupScript.

Quando mi tiro il controllo di segnaposto e il codice direttamente sulla pagina del Registro script funziona correttamente (sto usando il controllo di sé stessa come parametro).

ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);

Chiunque può gettare luce sul motivo per cui un iniettati di controllo su un Segnaposto impedirebbe lo ScriptManager dalla registrazione correttamente lo script?Sto indovinando che questo potrebbe avere qualcosa a che fare con il ciclo di vita di controlli di dinamica, ma apprezzerei (per mia conoscenza personale) se c'è un corretto processo di cui sopra.

È stato utile?

Soluzione

Penso che si dovrebbe essere utilizzando il Controllo di sovraccarico del RegisterStartupScript.

Ho provato il seguente codice in un server di controllo:

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")]
public class AlertControl : Control{
    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        string script = "alert(\"Hello!\");";
        ScriptManager.RegisterStartupScript(this, GetType(), 
                      "ServerControlScript", script, true);
    }
}

Poi nella mia pagina ho:

protected override void OnInit(EventArgs e){
    base.OnInit(e);
    Placeholder1.Controls.Add(new AlertControl());
}

Dove Placeholder1 è un segnaposto in un pannello di aggiornamento.Il segnaposto è un altro paio di controlli in esso, tra cui pulsanti.

Questo comportava esattamente come ci si aspetterebbe, ho ricevuto un avviso dicendo "Ciao" ogni volta che ho caricato la pagina o causato il pannello di aggiornamento per aggiornare.

L'altra cosa che si poteva guardare è quella di agganciare il ciclo di vita della pagina eventi che vengono generati durante un aggiornamento del pannello di richiesta:

Sys.WebForms.PageRequestManager.getInstance()
   .add_endRequest(EndRequestHandler);

Il PageRequestManager endRequestHandler l'evento si attiva ogni volta che un pannello di aggiornamento viene completato il suo aggiornamento, che permette di chiamare un metodo per impostare il vostro controllo.

Il mio solo altre domande sono:

  • Qual è il tuo script in realtà facendo?
  • Presumibilmente si può vedere lo script in HTML in fondo alla pagina (appena prima della chiusura </form> tag)?
  • Hai provato a mettere un paio di "alert("Qui");" chiamate nel vostro script di avvio per vedere se questo viene chiamato correttamente?
  • Hai provato con Firefox e Firebug - è che la segnalazione di eventuali errori di script?

Altri suggerimenti

Ho avuto un problema usando questo in un controllo utente (in una pagina funzionava bene); il Button1 si trova all'interno di un updatepanel e il scriptmanager si trova sul usercontrol.

protected void Button1_Click(object sender, EventArgs e)  
{  
    string scriptstring = "alert('Welcome');";  
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);  
}

Ora sembra che devi stare attento con i primi due argomenti, devono fare riferimento alla tua pagina, non al tuo controllo

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);

Quando si chiama ScriptManager.RegisterStartupScript, il " Control " Il parametro deve essere un controllo all'interno di un UpdatePanel che verrà aggiornato. Devi cambiarlo in:

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);

La soluzione è mettere gli script in un file js esterno (chiamiamolo 'yourDynamic.js') e registrare nuovamente il file ogni volta che aggiorni il pannello di aggiornamento.

Lo uso nell'evento updatepanel_prerender:

ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType(), "UpdatePanel1_PreRender", _
                   "<script type='text/javascript' id='UpdatePanel1_PreRender'>" & _
                   "include('yourDynamic.js');" & _
                   "removeDuplicatedScript('UpdatePanel1_PreRender');</script>" _
                   , False)

Nella pagina o in qualche altra inclusione avrai bisogno di questo javascript:

// Include a javascript file inside another one.
function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('src'))
        {
            if(scripts[x].getAttribute('src').indexOf(filename) != -1)
            {
                head.removeChild(scripts[x]);
                break;
            }
        }
    }

    script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';
    head.appendChild(script)
}

// Removes duplicated scripts.
function removeDuplicatedScript(id)
{
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('id'))
        {
            if(scripts[x].getAttribute('id').indexOf(id) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
    clearAjaxNetJunk();
}
// Evoids the update panel auto generated scripts to grow to inifity. X-(
function clearAjaxNetJunk()
{
    var knowJunk = 'Sys.Application.add_init(function() {';
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].textContent)
        {
            if(scripts[x].textContent.indexOf(knowJunk) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
}

Abbastanza bello, ah ... Jejeje Questa parte di ciò che ho pubblicato qualche tempo fa qui .

Spero che questo aiuto ... :)

Ho riscontrato un problema con Page.ClientScript.RegisterStartUpScript: non utilizzavo un pannello di aggiornamento, ma il controllo era memorizzato nella cache. Ciò significava che dovevo inserire lo script in un oggetto Literal (o che potevo usare un PlaceHolder), quindi quando viene reso dalla cache lo script è incluso.

Una soluzione simile potrebbe funzionare per te.

NON USARE GUID per chiave

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) 
       Guid.NewGuid().ToString(), myScript, true);

e se vuoi farlo, chiama Something Like questa funzione

 public static string GetGuidClear(string x)
 {
      return x.Replace("-", "").Replace("0", "").Replace("1", "")
              .Replace("2",  "").Replace("3", "").Replace("4", "")
              .Replace("5", "").Replace("6", "").Replace("7", "")
              .Replace("8", "").Replace("9", "");
 }

Ciò che ha funzionato per me è registrarlo sulla Pagina specificando il tipo come quello di UpdatePanel, in questo modo:

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);

A volte non si attiva quando lo script presenta un errore di sintassi, assicurarsi che la sintassi dello script e javascript sia corretta.

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

Il " true " valore param alla fine di ScriptManager.RegisterStartupScript aggiungerà un tag JavaScript all'interno della tua pagina:

<script language='javascript' defer='defer'>your script</script >

Se il valore sarà " false " inietterà solo lo script senza il tag --script--.

Provo molte cose e alla fine ho scoperto che l'ultimo parametro deve essere falso e devi aggiungere <SCRIPT> tag allo script java:

string script = "< SCRIPT >alert('hello!');< /SCRIPT>";

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top