2013-04-13 12 views
6

Widziałem podobne problemy z tym i odpowiedzi, ale nie wydaje się, aby rozwiązać problem.Program asp.net usercontrol nie uruchamia javascript wewnątrz updatepanel

Mam kontrolę użytkownika w panelu aktualizacji. Wewnątrz mojej kontroli użytkownika wyprowadzam javascript.

Po uruchomieniu javascript nie uruchomi się. Jeśli przeniesię javascript na stronę nadrzędną poza kontrolką usercontrol/updatepanels, uruchomi się. Nie ma to sensu, ponieważ nie mogę użyć tej kontroli użytkownika na innej stronie bez duplikowania kodu ... przez powielenie całego javascript (innej strony) lub dodanie odniesień do pliku .js na każdej stronie, z której jest on używany na (tej samej stronie). Jest po prostu mniej przenośny

Po prostu chcę wypisać javascript za pomocą kontrolki (w panelu aktualizacji).

Aktualizacja jest wymieniona z dokładnością tego, co robię. To nie działa, nawet jeśli umieszczę kontrolę użytkownika poza aktualizacjami.

Utrzymanie to proste (to nie działa dla mnie):

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> 

nadrzędny:

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

debugowanie w chromie mówi mi „Uncaught ReferenceError: test nie jest zdefiniowano "

Jeśli dodaję javascript bezpośrednio do onclick, jak poniżej, to t działa:

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

Jak wspomniano powyżej, przeniesienie funkcji do strony nadrzędnej działa również.

To tak, jakby przeglądarka ignorowała wyniki skryptu z formantu użytkownika.

Wszelkie pomysły?

+0

Twój kod działa dobrze dla mnie. – chamara

+0

@chamara Ten kod nie zadziała, jeśli zadzwonisz i zaktualizujesz go z poziomu panelu UpdatePanel. – Aristos

Odpowiedz

4

Kiedy masz i że UpdatePanel aktualizuje zawartość, traktuje jej zawartość jako prosty tekst/html (nie kod), nie ma żadnego parsera dostępnego do uruchomienia skryptu i udostępnienia go dla strony.

Więc ta treść,

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

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

kodu po stronie klienta po aktualizacji tras panelowych i aktualizacji zawartości strony, część skryptu nie jest analizowany - jego prosty text/html dla strony.

Część ta jednak przebiega

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

ponieważ parse atrybutu onclick odbywa się po kliknięciu na nim.

Są dostępne następujące rozwiązania:

  1. Przenieś swój skrypt do pliku zewnętrznego
  2. przeniesie Cię skryptu poza UpdatePanel
  3. zarejestruj skrypt w kod związany z RegisterClientScriptBlock lub alternatywnych funkcji.
+0

To nie różni się znacznie od tego, co stwierdziłem, że zadziałało w moim pytaniu. Jeśli muszę umieścić skrypt poza updatepanel to jestem zmuszony do włączenia go na stronie nadrzędnej ... Moja kontrola użytkownika znajduje się wewnątrz updatepanelu na stronie nadrzędnej ... i tak, umieszczenie skryptu poza tym updatepanel działa dobrze nawet bez użycia registerclientscriptblock ... Podczas gdy to działa, jest mniej niż pożądane. Na pewno MS dostarczyło sposób na włączenie javascript w kontrolerze użytkownika, jeśli nie, przenośność. –

+1

@AdamWood Możesz zarejestrować skrypt pod kodem. Różnica w mojej odpowiedzi na twoje pytanie polega na tym, że nie zdajesz sobie sprawy, że aktualizacja nie jest analizowana i nie może parsować skryptu - i to jest kluczowy punkt tutaj. – Aristos

+0

Thx. Wyjaśnia, dlaczego kod wbudowany w UserControl w ramach UpdatePanel nie jest w ogóle możliwy do wywołania. To tylko tekst. Wyszukiwanie godzin ... – Fried

-1

najlepszym sposobem radzenia sobie z javscript kodu, który jest związany z elementów DOM w ciągu UpdatePanel jest subskrybować endRequest przypadku PageRequestManager i wykonać swój kod tutaj. Na przykład chcesz ustawić tutaj obsługę zdarzeń click.

// 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') 
} 

Alternatywne rozwiązanie będzie używać event delegation tak:

function pageLoad() { 

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

} 

I mieć div z klasy o nazwie container wokół panelu aktualizacji. W takim przypadku Twój div.container nigdy nie jest usuwany z DOM, więc wszystkie funkcje obsługi zdarzeń będą po nim zachowywane.

sam kod bez jquery i przy użyciu tylko ASP.NET AJAX będzie wyglądać następująco:

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

Dzięki Aristos za wysłanie mnie na właściwą drogę ... Choć jego rozwiązanie działa, to nie odpowiedzieć na pytanie o wypuszczenie javascripta z wewnątrz usercontrol, ale zamiast tego zasugerowałem przeniesienie go na zewnątrz. Nie jest to pożądany wynik, jak stwierdzono, ponieważ nie jest on przechowywany w kontroli, co ułatwia przenoszenie.

Oto moje rozwiązanie, które realizuje to: plik CS:

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

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

Można by użyć StringBuilder jeśli skrypt jest dłuższy, ale Eitherway działa.

To powoduje, że kod pozostaje całkowicie wewnątrz kontrolki użytkownika i działa po zdarzeniu onclick znacznika.

1

Oprócz rozwiązania, które opublikował Adam Wood, powinienem powiedzieć, że musisz użyć skryptu ScriptManager, aby zarejestrować skrypt podczas korzystania z panelu aktualizacji, przynajmniej w .net 4.0, ponieważ w przeciwnym razie to nie zadziała.

Więc można umieścić na razie pageload w usercontrol:

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

Myślałem, że to było rozwiązanie innego problemu, który mam. Próbuję powiązać zdarzenie jquery z formantem. Ale otrzymuję 0x800a139e - błąd środowiska wykonawczego JavaScript: błąd składni, nierozpoznane wyrażenie: # <% = pnDetails.ClientID%>, s z jakiegoś powodu nie mam dostępu do kontrolek użytkownika w skrypcie. (Próbuję tego tak, ponieważ jeśli umieszczę skrypt na mojej kontroli użytkownika, która znajduje się wewnątrz panelu aktualizacji, mój skrypt nie uruchamia się wcale). – SoroTrestal

0

spróbuj tego;

Możesz odnaleźć swoje elementy skryptu po wywołaniu wywołania panelu udpdate i je ocenić.

Dodaj specjalny atrybut do wbudowanego znacznika skryptu, aby wybrać elementy po żądaniu wywołania zwrotnego.

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

Dodaj ten skrypt do pliku aspx kontenera panelu aktualizacji.

<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> 
Powiązane problemy