2010-05-19 6 views
5

Ок: У меня есть UpdatePanel на странице aspx, которая содержит один Placeholder.Код JavaScript внутри UpdatePanel

Внутри этого заполнителя Я добавляю один из элементов пользовательского контроля в зависимости от определенных внешних условий (это страница конфигурации).

В каждом из этих usercontrols есть функция javascript bindUcEvents(), которая связывает различные события jQuery и javascript с кнопками и валидаторами внутри usercontrol.

Проблема, с которой я сталкиваюсь, заключается в том, что javascript usercontrol не распознается. Как правило, javascript внутри обновляемой панели выполняется, когда обновляемая панель отправляется обратно, однако ни один из этих кодов не может быть найден на странице (я попытался запустить эту функцию вручную через консоль firebug, но он говорит мне, что не может найти эту функцию).

Есть ли у кого-нибудь предложения?

Cheers, ред.

EDIT:

вырубить (но функциональный) пример:

Markup:

<script src="/js/jquery-1.3.2.min.js"></script> 
    <form id="form1" runat="server"> 
    <div> 

    <asp:ScriptManager ID="Script" runat="server" /> 

    <asp:Button ID="Postback" runat="server" Text="Populate" OnClick="PopulatePlaceholder" /> 

    <asp:UpdatePanel ID="UpdateMe" runat="server"> 
    <Triggers> 
     <asp:AsyncPostBackTrigger ControlID="Postback" EventName="Click" /> 
    </Triggers> 
     <ContentTemplate> 
      <asp:Literal ID="Code" runat="server" /> 
      <asp:PlaceHolder ID="PlaceMe" runat="server" /> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
    </div> 
</form> 

C#:

protected void PopulatePlaceholder(object sender, EventArgs e) 
{ 
    Button button = new Button(); 
    button.ID = "Push"; 
    button.Text = "push"; 
    button.OnClientClick = "javascript:return false;"; 
    Code.Text = "<script type=\"text/javascript\"> function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents(); </script>"; 
    PlaceMe.Controls.Add(button); 
} 

Вы увидите, что кнопка не poput предупреждение, даже несмотря на то, что код присутствует на странице.

EDIT2:

Хорошо, просто чтобы понять, код продукции значительно сложнее, чем просто одной функции, связанной на буквальный, и содержит большое количество

<%= Control.ClientID %> 

бит код, который будет очень сложно отнести к неспецифическим функциям, и бессмысленно, поскольку каждый из них используется только в одном месте (мы говорим о очень конкретной проверке и нечетном триггете popup + некоторая логика).

+1

Можете ли вы опубликовать часть исходного кода или сгенерированный код? без него это очень трудно диагностировать. – scunliffe

+0

уверен, я просто стараюсь избегать этого, потому что его довольно много, я попытаюсь немного сократить его. –

+0

Вы заявили, что у вас много кода, и поэтому он не находится в коде. .. Так где же это? В aspx? Во внешнем js-файле? Загружается из файла базы данных/xml и считывается кодом позади? – Stobor

ответ

8

Избавьтесь от этого управления Literal и используйте ScriptManager для регистрации вашего скрипта. То, что вы делаете, не работает по той же причине

window.document.getElementById('someId').innerHtml = "<script type=\"text/javascript\">alert('hey');</script>"; 

не работает. Попробуйте следующее:

protected void PopulatePlaceholder(object sender, EventArgs e) 
{ 
    Button button = new Button(); 
    button.ID = "Push"; 

    button.Text = "push"; 
    button.OnClientClick = "return false;"; 


    string script = "function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents();"; 

    ScriptManager.RegisterClientScriptBlock(this.Page, typeof(SomeClass), Guid.NewGuid().ToString(), script, true); 


    PlaceMe.Controls.Add(button); 
} 

Параметры для RegisterClientScriptBlock могут потребоваться изменить, но вы получите эту идею.

+3

ремонтируемость снижается до нуля, но если я это сделаю: мы говорим о 200 строках JS, которые делают много вещей, большинство из которых используют контрольные идентификаторы клиентов для этого. такой код очень сложно поддерживать, когда он находится в бэкэнде ... –

+1

Затем вам нужно реорганизовать свои сценарии. Это правильный способ сделать это. Сожалею. –

+1

т. Е. Вам придется переписать сценарии, чтобы их можно было разместить в js-файлах. Затем вам нужно будет вызвать ScriptManager.RegisterClientScriptBlock и ScriptManager.RegisterStartupScript по мере необходимости. Невозможно получить то, что вы пытаетесь сделать, чтобы работать без вызовов ScriptManager. Скрипты в ascx/aspx в любом случае не являются хорошей практикой и не помогают производительности. –

2

Добавьте скриптмена (расширения Ajax) на свою страницу и добавьте ссылки на скрипт внутри этого менеджера. Менеджер загрузит каждый тег сценария на основе ajax-pageload (а не только на начальной загрузке) - переместите весь необходимый код javascript внутри панели обновлений, и вы в значительной степени сделали.

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
     <Scripts> 
      <asp:ScriptReference Path="../lib/jquery-1.2.6.pack.js" /> 

Не прочитал вопрос достаточно хорошо (и без образца). См. Мой новый ответ.

+1

Вам нужен сценарист для использования обновляемых панелей, и код является внутренним для usercontrol (встроен на страницу), так как он использует идентификаторы, специфичные для управления, поэтому это не очень полезно для поиска. –

5

Чтобы повторно запустить некоторые JS после обновления панели уволила Я всегда использовал этот

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
    function(sender, args) { 
     //update whatever here 
    }); 

Кроме того, если у вас есть какие-либо ссылки на элементы внутри панели обновления вы можете обновить эти переменные в пределах этой функции также, иначе у вас будут старые ссылки, которые не будут работать.

+0

Да, это, к сожалению, работает только в том случае, если код присутствует на исходной странице в первую очередь. Поскольку я использую динамические элементы управления и загружаю его через UpdatePanel (т. Е. Через javascript), новые функции javascript не распознаются как функции! –

+0

Хммм ... Я знаю, что evals - это не лучшая вещь, на которую можно вернуться, но как насчет того, чтобы этот вызов был включен в обратный вызов UpdatePanel, указанный выше? ... // обновлять все здесь eval (document.getElementById ('Code'). InnerHtml); ... – Justin

+0

может работать, но это в значительной степени последняя вещь, к которой я бы хотел обратиться! –

-1

Как-то кажется, ваш код.Текст теряется в переводе где-то - не знаю специфики, возможно, это по дизайну; в любом случае на следующем же работу:

protected void PopulatePlaceholder(object sender, EventArgs e) 
    { 
     Button button = new Button(); 
     button.ID = "Push"; 
     button.Text = "push"; 
     button.OnClientClick = "javascript:return false;"; 
//  Code.Text = 
     PlaceMe.Controls.Add(button); 
     PlaceMe.Controls.Add(new LiteralControl("<script type=\"text/javascript\"> function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents(); </script>")); 
    } 

Поскольку вы уже строите яваскрипт код из кода вы можете также добавить элемент управления динамически тоже.

+0

Этот небольшой пример показывает только мой процесс, реальный код составляет около 200 строк javascript, что делает некоторые очень сложные вещи. Мне нужно его поддерживать, поэтому на самом деле нет возможности сохранить javascript в коде! –

+0

В вашем примере вы уже строите Code.Text от codebehind; вы заявляете, что не хотите выполнять javascript из кода? Я предположил, что вы замените предупреждение вызовом новой функции, передав ID как параметр или что-то в этом роде, в любом случае - просто пытаюсь помочь – riffnl

+0

Я понимаю, что, однако, я сказал, что было больше для него в моем оригинальном посте. –

0

Может быть, вы ищете это: http://api.jquery.com/live/

Почти .bind(), совместимые (исключения, перечисленные в приведенной выше ссылке) - но также связывается с элементами добавленных/измененных позже.

Или, может быть, дать также .delegate() попытка - не может напрямую заменить вызовы .bind(), но в большинстве случаев намного быстрее.

Смежные вопросы