UpdatePanel 中的 JavaScript 代码

Posted

技术标签:

【中文标题】UpdatePanel 中的 JavaScript 代码【英文标题】:JavaScript code inside UpdatePanel 【发布时间】:2011-02-21 07:20:38 【问题描述】:

好的:我在一个包含单个占位符的 aspx 页面上有一个 UpdatePanel。

在这个占位符中,我根据某些外部条件附加了一个用户控件选择(这是一个配置页面)。

在每个用户控件中都有一个 bindUcEvents() javascript 函数,它将各种 jQuery 和 javascript 事件绑定到用户控件内的按钮和验证器。

我遇到的问题是用户控件的 javascript 未被识别。通常,当更新面板回发时,更新面板内的 javascript 会被执行,但是页面找不到这些代码(我尝试通过萤火虫的控制台手动运行该函数,但它告诉我找不到该函数)。

有人有什么建议吗?

干杯,埃德。

编辑:

减少(但功能)示例:

标记:

<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);

您会看到该按钮不会弹出警报消息,即使页面上存在代码。

EDIT2:

好吧,明确一点,生产代码比绑定到文字上的单个函数要复杂得多,并且包含大量

<%= Control.ClientID %>

一些代码很难分解成非特定函数,而且毫无意义,因为它们每个都只在一个地方使用(我们正在谈论非常具体的验证和奇怪的弹出触发器 + 一些逻辑) .

【问题讨论】:

你能发布一些源代码或生成的代码吗?没有它,这很难诊断。 当然,我只是倾向于避免这样做,因为有很多,我会尽量减少一点 你说你有很多代码,所以它不在代码隐藏中......那么它在哪里?在 aspx 中?在外部 js 文件中?从数据库/xml 文件加载并由后面的代码读取? 【参考方案1】:

也许你正在寻找这个:http://api.jquery.com/live/

几乎 .bind() 兼容(上面链接中列出的例外情况)-但也绑定到稍后添加/更改的元素。

或者也可以尝试 .delegate() - 不能直接替换 .bind() 调用,但在大多数情况下要快得多。

【讨论】:

【参考方案2】:

摆脱 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 的参数可能需要更改,但你明白了。

【讨论】:

如果我这样做,可维护性将降至零:我们谈论的是 200 行 JS,它们做了很多事情,其中​​大部分使用控制客户端 ID 来完成。这种代码在后端很难维护...... 你需要重构你的脚本。这是这样做的正确方法。对不起。 也就是说,你必须重写你的脚本,以便它们可以放在 js 文件中。然后,您必须根据需要调用 ScriptManager.RegisterClientScriptBlock 和 ScriptManager.RegisterStartupScript。如果不调用 ScriptManager,您将无法获得您想要做的工作。 ascx/aspx 中的脚本无论如何都不是好习惯,也无助于提高性能。 天哪,很抱歉发布答案。然后发布答案。 很抱歉浪费您的时间。你能发布你的答案吗?【参考方案3】:

将脚本管理器(Ajax 扩展)添加到您的页面并在该管理器中添加您的脚本引用。 管理器将在基于 ajax 的页面加载(而不仅仅是初始加载)上加载每个脚本标签 - 将所有需要的 javascript 代码移动到更新面板中,您就大功告成了。

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

没有很好地阅读问题(并且没有示例)。查看我的新回复。

【讨论】:

您需要一个脚本管理器来使用更新面板,并且代码都在用户控件内部(嵌入在页面中),因为它使用特定于控件的 ID,所以这并没有真正的帮助。跨度> 【参考方案4】:

您的 Code.Text 似乎不知何故在翻译中丢失了 - 不知道具体细节,也许是设计使然;无论如何,下一个确实有效:

    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>"));
    

由于您已经从代码隐藏构建了 javascript 代码,因此您也可以动态添加控件。

【讨论】:

这个小例子只是说明我的过程,真正的代码是大约 200 行 javascript 代码,它做了一些非常复杂的事情。我需要维护它,所以实际上没有将javascript保留在代码后面的选项! 在您的示例中,您已经从代码隐藏构建了 Code.Text;您现在说您不想从代码隐藏执行 javascript?我假设你会用对新函数的调用替换警报,将 ID 作为参数传递或类似的东西,无论如何 - 只是想提供帮助 我明白这一点,但我确实说过在我的原始帖子中还有更多内容。 最后一个选项;也许启用代码文字控件的视图状态会在回调上做点什么?【参考方案5】:

要在更新面板触发后重新运行一些 js,我一直使用这个

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

此外,如果您对更新面板中的元素有任何引用,您也可以在该函数中刷新这些变量,否则您将拥有无法工作的旧引用。

【讨论】:

是的,不幸的是,只有当代码首先出现在原始页面上时才有效。由于我正在使用动态控件并通过 UpdatePanel(即通过 javascript)加载它,因此新的 javascript 函数不会被识别为函数! 嗯...我知道评估不是最好的依靠,但是将这个调用放在上面列出的 UpdatePanel 回调中呢? ... //更新这里的任何内容 eval(document.getElementById('Code').innerHtml); ... 可能会奏效,但这几乎是我最不想采取的措施! 这对我来说非常合适。不错!

以上是关于UpdatePanel 中的 JavaScript 代码的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript提高:006:ASP.NET使用easyUI TABS标签updatepanel

从 UpdatePanel 异步回发后,嵌入式 javascript 不起作用

ASP.NET UpdatePanel:在 UpdatePanel 更新上注入 Javascript

IE 中的 UpdatePanel 缓慢

使用 JavaScript 或 jQuery 手动更新 UpdatePanel

如何从 JavaScript 更新 UpdatePanel