2010-05-13 4 views
12

Di seguito è riportato il codice attualmente implementato.Come verificare se lo script client è già registrato durante un postback parziale

if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey)) 
{ 
    ScriptManager scriptManager = ScriptManager.GetCurrent(page); 
    if (scriptManager != null && scriptManager.IsInAsyncPostBack) 
    { 
    //if a MS AJAX request, use the Scriptmanager class 
    ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true); 
    } 
    else 
    { 
    //if a standard postback, use the standard ClientScript method 
    Page.ClientScript.RegisterStartupScript(Page.GetType(), scriptKey, script, true); 
    } 
} 

che sto facendo come suggerito in this risposta in modo che possa registrare script di avvio su entrambe le volte cioè quando c'è postback parziale e un postback completo.

Il problema è Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey) sempre (anche quando lo script è registrato prima) restituisce false quando si tratta di postback parziale. E non sono riuscito a trovare il metodo ScriptManager.IsStartupScriptRegistered (statico). Di conseguenza, uno script aggiuntivo viene emesso su tutti i postback parziali/asincroni.

Si noti che sto utilizzando lo script manager di AjaxControlToolkit versione 4.1, ovvero ToolkitScriptManager nella mia pagina principale. Ma non ho niente a che fare con questo.

UPDATE

<asp:UpdatePanel ID="ContactDetailsUpdatePanel" UpdateMode="Conditional" runat="server"> 
    <Triggers> 
     <asp:AsyncPostBackTrigger ControlID="UpdateContactDetailsButton" EventName="Click" /> 
    </Triggers> 
    <ContentTemplate> 
     <div id="ContactDetailsContent" class="contact_details_content"> 
     <div class="customer_contactdetails_left_pane"> 
      <div class="customer_name_field"> 
      <asp:Label ID="CustomerNameLabel" runat="server" Text="Customer" /> 
      <asp:TextBox ID="CustomerNameValue" runat="server" /> 
      </div> 
      <div class="customer_address_field"> 
      <asp:Label ID="CustomerAddressLabel" runat="server" Text="Address" /> 
      <asp:TextBox ID="CustomerAddressValue" runat="server" /> 
      <asp:TextBox ID="CustomerAddressValue1" runat="server" /> 
      <asp:TextBox ID="CustomerAddressValue2" runat="server" /> 
      <asp:TextBox ID="CustomerAddressValue3" runat="server" /> 
      </div> 
      <div class="customer_postcode_field"> 
      <asp:Label ID="CustomerPostcodeLabel" runat="server" Text="Postcode" /> 
      <asp:TextBox ID="CustomerPostcodeValue" runat="server" /> 
      </div> 
     </div> 
     <div class="customer_contactdetails_right_pane"> 
      <div> 
      <asp:Label ID="CustomerContactLabel" runat="server" Text="Contact" /> 
      <asp:TextBox ID="CustomerContactValue" runat="server" /> 
      </div> 
      <div> 
      <asp:Label ID="CustomerTelephoneLabel" runat="server" Text="Telephone" /> 
      <asp:TextBox ID="CustomerTelephoneValue" runat="server" /> 
      </div> 
      <div> 
      <asp:Label ID="CustomerMobileLabel" runat="server" Text="Mobile" /> 
      <asp:TextBox ID="CustomerMobileValue" runat="server" /> 
      </div> 
      <div> 
      <asp:Label ID="CustomerFaxLabel" runat="server" Text="Fax" /> 
      <asp:TextBox ID="CustomerFaxValue" runat="server" /> 
      </div> 
      <div> 
      <asp:Label ID="CustomerEmailLabel" runat="server" Text="Email" /> 
      <asp:TextBox ID="CustomerEmailValue" runat="server" /> 
      </div> 
      <div> 
      <asp:Label ID="CustomerWebLabel" runat="server" Text="Web" /> 
      <asp:TextBox ID="CustomerWebValue" runat="server" /> 
      </div> 
     </div> 
     </div> 
     <div class="update_button_field"> 
     <asp:Button ID="UpdateContactDetailsButton" runat="server" Text="Update" 
      onclick="UpdateContactDetailsButton_Click" /> 
     </div>   
    </ContentTemplate>  
    </asp:UpdatePanel> 

Grazie in anticipo.

NOTA: Per essere in grado di comprendere i progressi su questo problema, vedere i commenti sulla risposta this prima di rispondere.

UPDATE
Ho implementato una soluzione temporanea a questo problema mettendo un controllo in javascript che se lo script è già in esecuzione, allora non lo esegue due volte. Javascript viene ancora sputato più volte su ogni postback parziale. Non posso impedirlo.

Mentre le visualizzazioni di questo post sono in aumento, posso vedere che ci sono altre persone che potrebbero anche voler rispondere a questo problema.

risposta

0
+0

Per informazioni sull'intero problema, visitare http://stackoverflow.com/questions/1952817/asp-net-javascript-inside-ajax-updatepanel/1953122#1953122. Page.ClientScript.IsStartupScriptRegistered() mi fornisce solo http://msdn.microsoft.com/en-us/library/62d1676x.aspx. E restituisce sempre false in caso di post backs parziali. – IsmailS

+0

Ho aggiunto markup ora. – IsmailS

+0

Questo non mi ha aiutato. Non so chi abbia votato. Sto già usando questo metodo ed è menzionato nella mia domanda. – IsmailS

1

Tenete a mente la prima linea di codice è l'inverso del valore di ritorno metodo perché della !.

if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey)) 

Se IsStartupScriptRegistered sta tornando false come dici tu, allora l'istruzione if dovrebbe valutare true a causa della !. Ciò dovrebbe causare la registrazione dello script come previsto.

Il codice è basato su my answer here, basato su ASP.NET AJAX 1.0 e ASP.NET 2.0. Potrebbe avere qualcosa a che fare con .NET 3.5, anche se credo di aver già usato quanto sopra in un nuovo progetto che abbiamo fatto sotto 3.5 e ha funzionato bene ...

Puoi postare qualche markup per andare con il codice ?

MODIFICA: Grazie per aver pubblicato il markup.

ho notato 2 cose ora:

lei ha citato si utilizza ToolkitScriptManager. È un controllo che eredita da ScriptManager. Non ho notato questo prima, ma il tuo codice fa ancora riferimento a ScriptManager direttamente.Hai detto che era durante i postback asincroni che lo script non funzionava, il che mi porta a credere che sia un problema con il tuo riferimento a ScriptManager. Non ho mai usato ToolkitScriptManager prima quindi non posso darti il ​​codice esatto, ma posso dirti che probabilmente dovrai aggiornare il code-behind, cambiando tutti i riferimenti a ScriptManager e i suoi metodi/proprietà all'equivalente in ToolkitScriptManager .

Prova ad aggiungere un punto di interruzione sull'istruzione if e assicurati che la valutazione sia vera. Non sarei sorpreso se scriptManager è null o scriptManager.IsInAsyncPostBack è false perché stai usando ToolkitScriptManager.

ScriptManager scriptManager = ScriptManager.GetCurrent(page); 
if (scriptManager != null && scriptManager.IsInAsyncPostBack) 
{ 
    //if a MS AJAX request, use the Scriptmanager class 
    ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true); 
} 

Infine - Il tuo markup guarda bene, diverso da quello che non è necessario la sezione <Triggers>. I trigger consentono di specificare il controllo che si trova all'esterno del pannello di aggiornamento per causare rendering parziali. Qualsiasi controllo figlio del pannello di aggiornamento all'interno della sezione <ContentTemplate> lo farà automaticamente. Il pulsante che hai scelto come target nella sezione Trigger è già incluso nel pannello di aggiornamento. Anche se non penso che questa sia la causa del tuo problema, lo rimuoverei comunque.

Spero che questo aiuti.

+0

Penso che non ci siano problemi con '!' Dato che voglio registrare lo script solo quando è ** non ** già registrato. Sì, il mio codice è basato sulla tua risposta. È già menzionato nella mia domanda. Grazie ancora per l'assistenza. Pubblicherò il markup quando andrò in ufficio il lunedì. Non ce l'ho adesso. Fondamentalmente il postback viene eseguito da un pulsante all'interno di un pannello di aggiornamento che si trova all'interno di TabContainer di AjaxControlToolkit. – IsmailS

+0

@KP! Ho aggiunto il markup ora. – IsmailS

+0

@Ismail ok Ho inviato un aggiornamento alla mia risposta. Penso che il tuo problema è che stai facendo riferimento a ScriptManager mentre stai usando ToolkitScriptManager. (vedi sopra) –

2

Avevo implementato una soluzione temporanea a questo problema inserendo un controllo in javascript che se lo script è già in esecuzione, non eseguire due volte. Javascript viene ancora sputato più volte su ogni postback parziale. Non posso impedirlo.

+0

Questo è stato concesso molto tempo fa, ma hai mai trovato qualcosa di meglio? – paqogomez

+0

Nops. Nei miei ulteriori progetti, non ho mai usato Microsoft Ajax Controls. Quindi non ha affrontato questo di nuovo. – IsmailS

2

Ho scritto un metodo di estensione per verificare se lo script è già stato registrato con ScriptManager. È possibile utilizzare lo stesso principio per controllare script di avvio:

public static bool IsClientScriptBlockRegistered(this ScriptManager sm, string key) 
     { 
      ReadOnlyCollection<RegisteredScript> scriptBlocks = sm.GetRegisteredClientScriptBlocks(); 

      foreach (RegisteredScript rs in scriptBlocks) 
      { 
       if (rs.Key == key) 
        return true; 
      } 

      return false; 
     } 
+0

+1 Sembra buono. Ma non so se funzionerà anche se gli script client sono già registrati in AsyncPostBacks con la stessa chiave. Dovrò controllare prima di accettarlo come risposta. – IsmailS

+0

L'ho provato e non si ricorda di quelli precedenti. – jheizer

4

Mi sono imbattuto in questo stesso problema durante la scrittura di un controllo composito in ASP.Net. Quando il controllo era all'interno di un pannello di aggiornamento, Page.ClientScript.IsStartupScriptRegistered non funzionava. Da all'interno del metodo protected override CreateChildControls void() stavo facendo qualcosa di simile

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true); 

Quindi mi sono imbattuto in una situazione simile a ciò che si descrive qui. Ciò che ha risolto il mio problema è stato passare il controllo e il suo tipo anziché il tipo di pagina e pagina a ScriptManager.RegisterStartupScript. Di qui il codice ora sembra,

ScriptManager.RegisterStartupScript(this, this.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true); 

Una volta che ho fatto questo cambiamento non ho più bisogno di controllare Page.ClientScript.IsStartupScriptRegistered. Ora il mio controllo funziona con o senza pannelli di aggiornamento. Neanche spute da js non necessarie. Spero che questo aiuti

9

Se si utilizza questo;

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "noPasswordMatch", script, true); 

Poi per verificare se è stato registrato è necessario utilizzare questo:

if (Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "noPasswordMatch")) 

if (Page.ClientScript.IsClientScriptBlockRegistered("noPasswordMatch")) non funziona!