2013-04-13 10 views
6

Ho visto problemi simili a questo e risposte ma nessuno sembra risolvere il problema.asp.net usercontrol non sparerà javascript all'interno updatepanel

Ho un controllo utente all'interno di un pannello di aggiornamento. All'interno del mio controllo utente emetto javascript.

Il javascript non si attiva quando viene attivato. Se sposto il javascript nella pagina padre al di fuori di usercontrol/updatepanels, viene attivato. Non ha senso farlo perché non posso usare questo usercontrol su un'altra pagina senza duplicare il codice ... duplicando l'intero javascript (sito diverso) o aggiungendo riferimenti a un file .js in ogni pagina utilizzata su (stesso sito). È solo meno portatile

Voglio semplicemente emettere il javascript con il controllo (all'interno del pannello di aggiornamento).

Il pannello di aggiornamento è menzionato per la precisione di ciò che sto facendo. Non funziona anche se metto l'usercontrol fuori dagli updatepanel.

mantenerlo semplice (Questo non funziona per me):

UserControl:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="_location.ascx.cs" Inherits="_location" %> 
<script type="text/javascript"> 
    function test() { 
     alert('Hello World!'); 
    } 
</script> 

<a href="javascript:void(0);" onclick="javascript:test();"> 
    Find For Me 
</a> 

GENITORE:

<uc1:_location runat="server" ID="_location" /> 

debug in cromo mi dice "ReferenceError Uncaught: test non è definito "

Se aggiungo il javascript direttamente a onclick come di seguito, i t works:

onclick="alert('Hello World!');" 

E come detto sopra, lo spostamento della funzione nella pagina padre funziona ANCHE.

È come se il browser ignorasse l'output dello script dal controllo utente.

Qualche idea?

+0

Il tuo codice funziona bene per me. – chamara

+0

@chamara Questo codice non funzionerà se lo chiami e lo aggiorni da dentro un UpdatePanel. – Aristos

risposta

4

Quando si dispone di un UpdatePanel e che UpdatePanel aggiornamenti il ​​suo contenuto, per trattamento il suo contenuto più semplice text/html (non il codice), non ha alcun parser a disposizione per eseguire lo script e renderlo disponibile per la pagina.

Quindi questo contenuto,

<script type="text/javascript"> 
    function test() { alert('Hello World!'); } 
</script> 

<a href="javascript:void(0);" onclick="javascript:test();"> 
    Find For Me 
</a> 

dopo il cliente che il codice lato di piste pannello di aggiornamento e contenuti gli aggiornamenti della pagina, la parte script non viene analizzato - la sua semplice text/html per la pagina.

Questa parte però corre

<a href="javascript:void(0);" onclick="alert('Hello World!');">Find For Me</a> 

perché il parse dell'attributo onclick è fatto quando si fa clic su di esso.

Non ci sono soluzioni alternative seguenti disponibili:

  1. spostare il vostro javascript in file esterno
  2. Muovi è scritto al di fuori della UpdatePanel
  3. Registrati lo script nel codice dietro con RegisterClientScriptBlock o alternative funzioni.
+0

Questo non è molto diverso da come ho affermato nella mia domanda. Se devo mettere lo script all'esterno dell'aggiornamento allora sono costretto a includerlo nella pagina padre ... Il mio usercontrol è all'interno di un updatepanel sulla pagina madre ... e sì, mettendo lo script all'esterno di quel updatepanel funziona bene anche senza usare un registro registerclientsblock ... Mentre questo funziona, è meno che desiderabile. Certamente MS ha fornito un modo per includere javascript all'interno di un controllo elettronico per, se non altro, la portabilità. –

+1

@AdamWood È possibile registrare lo script sul codice sottostante. Il diverso nella mia risposta alla tua domanda, è che non ti rendi conto che l'aggiornamento non viene analizzato e non può analizzare la sceneggiatura - e questo è il punto chiave qui. – Aristos

+0

Thx. Spiega perché il codice inline su un UserControl all'interno di un UpdatePanel non è affatto chiamabile. È solo testo. Cercando ore ... – Fried

-1

modo preferito di trattare con il codice javscript che è destinata a elementi DOM all'interno UpdatePanel è quello di iscriversi a endRequest caso di PageRequestManager ed eseguire il codice qui. Ad esempio, si desidera impostare gestori di eventi click qui.

// that is standard way for asp.net to execute JS on page load 
// pretty much the same as $(function(){ ...}) with jquery 
function pageLoad() { 
    // find PRM instance and subscribe to endRequest 
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest); 
} 

function endRequest() { 
    // set all handlers to DOM elements that are within UpdatePanel 
    $('<%= myButton.ClientID %>').on('click', test) 
} 

function test(e) { 
    alert('Hi') 
} 

soluzione alternativa sarà quella di utilizzare event delegation in questo modo:

function pageLoad() { 

    // delegate click event on .myButton inside .container 
    // to the .container DOM element 
    $('.container').on('click', '.myButton', test) 

} 

E hanno div con una classe denominata container intorno al vostro pannello di aggiornamento. In questo caso il tuo div.container non viene mai rimosso dal DOM, quindi tutti i gestori di eventi su di esso manterranno dopo i postback parziali.

stesso codice jQuery e utilizzando solo ajax asp.net sarà simile a questa:

function pageLoad() { 
    Sys.UI.DomEvent.addHandler($("myContainer"), "click", delegatedTest); 
} 

function delegatedTest(e) { 
    // since asp.net ajax does not support event delegation 
    // you need to check target of the event to be the right button 
    if (e.target.id == "myButton") test(e) 
} 

function test(e) { 
    alert("HI") 
} 
1

Grazie a Aristos per avermi inviato la strada giusta ... Anche se la sua soluzione funziona, ma non ha risposto alla questione di emettere il javascript da dentro l'usercontrol ma suggerito invece di spostarlo all'esterno. Questo non era il risultato desiderato, come affermato, in quanto non è tenuto all'interno del controllo per una più facile portabilità.

Ecco la mia soluzione che compie questo: lima CS:

String script = "<script type=\"text/javascript\">"; 
script += "function test() {"; 
    script += "alert('Hello World!');"; 
script += "</script>"; 

Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script); 

Si potrebbe utilizzare uno StringBuilder se lo script è più lungo, ma Eitherway funziona.

Ciò mantiene il codice interamente all'interno di usercontrol e funziona dall'evento onclick del tag.

1

In aggiunta alla soluzione che ha pubblicato Adam Wood, devo dire che è necessario utilizzare ScriptManager per registrare lo script quando si utilizza il pannello di aggiornamento, almeno in. NET 4.0 perché altrimenti non funzionerà.

Così si può mettere sul caso PageLoad di UserControl:

string script = @" alert('this is a test'); 
alert('it worked')"; 
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true); 
+0

Ho pensato che questa fosse la soluzione ad un altro problema che ho. Sto cercando di associare un evento jquery a un controllo. Ma ricevo 0x800a139e - Errore di runtime JavaScript: Errore di sintassi, espressione non riconosciuta: # <% = pnDetails.ClientID%>, s per qualche motivo non riesco ad accedere ai miei controlli utente nello script. (Lo sto provando in questo modo perché se metto lo script sul mio controllo utente, che risiede all'interno di un Pannello di aggiornamento, il mio script non si attiva affatto). – SoroTrestal

0

Prova questa;

È possibile trovare gli elementi di script dopo la richiamata del pannello udpdate e valutarli.

Aggiungere un attributo speciale al tag di script in linea per selezionare gli elementi dopo la richiesta di richiamata.

<script type="text/javascript" data-tag='myscript'> 
    function test() { 
     alert('Hello World!'); 
    } 
</script> 

E aggiungere questo script al file del contenitore di aggiornamento del pannello di aggiornamento.

<script> 

     if (Sys !== undefined) { 
      var prm = Sys.WebForms.PageRequestManager.getInstance(); 
      prm.add_endRequest(endPostbackRequest); 
     } 

     function endPostbackRequest(sender, args) { 
      $("script[data-tag='myscript']:not([data-run])").each(
       function() { 
        eval.apply(window, [$(this).text()]); 
        $(this).attr('data-run', '1'); 
       }); 
     } 

</script> 
Problemi correlati