ScriptManager.RegisterClientScriptIninclude 在 UpdatePanel 中不起作用

发布于 2024-08-15 06:19:02 字数 3876 浏览 1 评论 0原文

我已浏览网络,但尚未找到以下问题的解决方案。我有这个示例页面(_ScriptManager.aspx),其中包含一个 ScriptManager、一个 UpdatePanel、一个带有两个 ViewsMultiView和两个 LinkBut​​tons 两个视图之间的切换。第二个视图包含一些我想要为其加载 JavaScript 文件(_ScriptManager.js)的功能。

因为我不知道用户是否会访问视图 2,所以我不想为每个请求静态包含 javascript 文件。我只想在需要时加载它。因此,我需要在异步回发期间包含脚本文件,这就是我使用 ScriptManager.RegisterClientScriptInclude 的目的。痛苦是:它不起作用。脚本 include 不知何故未在客户端执行,因此无法使用其中的 javascript 函数。更糟糕的是,我在 ScriptManager.RegisterStartupScript 中注册的脚本块在这种情况下不会被执行!这一切都非常令人恼火。有趣的是,包含脚本和脚本块确实通过异步回发发送到客户端(Fiddler 是我的朋友:-)),并且脚本文件也被加载。但后来 JavaScript 似乎以某种方式崩溃了......

有人知道或知道报告的错误吗?

_ScriptManager.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="_ScriptManager.aspx.cs" Inherits="Frontend.Web._Tests.ScriptManagerTest" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title></title>
  <script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js"></script>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="scm"></asp:ScriptManager>
    <asp:Label runat="server" ID="lbOut">Outside of UpdatePanel</asp:Label>
  <div style="border: solid 1px red;">
      <asp:UpdatePanel runat="server" ID="up" UpdateMode="Conditional">
        <ContentTemplate>
          <div>
            <asp:LinkButton runat="server" ID="btnFirst">Show view 1</asp:LinkButton>
            <asp:LinkButton runat="server" ID="btnSecond">Show view 2</asp:LinkButton>
          </div>
          <div>
            <asp:MultiView runat="server" ID="mv">
              <asp:View runat="server" ID="vw1">First view - static content</asp:View>
              <asp:View runat="server" ID="vw2">
                Second view - dynamically loaded content (between dashes): 
                <div>#<span id="divDyn"></span>#</div>
              </asp:View>
            </asp:MultiView>
          </div>
        </ContentTemplate>
      </asp:UpdatePanel>
  </div>
  </form>
</body>
</html>

_ScriptManager.js(这里我只是向 id=divDyn 的跨度添加一些动态内容):

function dynamic() {
  alert('dynamic');
  $('#divDyn').text('Dynamic!');
}

_ScriptManager.aspx.cs代码隐藏:

public partial class ScriptManagerTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        btnFirst.Click += delegate { mv.SetActiveView(vw1); };
        btnSecond.Click += delegate { mv.SetActiveView(vw2); };

        if (!IsPostBack)
        {
            // Test 1: does not work
            mv.SetActiveView(vw1);

            // Test 2: works, because required script is loaded on initial page request
            //mv.SetActiveView(vw2);
        }
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (mv.GetActiveView() == vw2)
        {
            // Not calling the RegisterClientScriptInclude
            // makes the alert work in both cases, but this is
            // what it's all about: including script only when
            // needed!
            ScriptManager.RegisterClientScriptInclude(
                Page, Page.GetType(), "include-js",
                ResolveClientUrl("~/ScriptManager.js"));
            ScriptManager.RegisterStartupScript(
                this, GetType(), "call-dynamic",
                "alert('hi there'); dynamic();", true);    
        }
    }
}

I've read through the net but haven't found a solution to the following problem. I have this example page (_ScriptManager.aspx) with a ScriptManager, an UpdatePanel, a MultiView with two Views and two LinkButtons two switch between the views. The second view contains some functionality which I want to load a JavaScript file for (_ScriptManager.js).

Since I don't know whether the user will ever visit view 2 I don't want to include the javascript file statically on for every request. I only want to load it if and when I need it. So I need to include the script file during an asynchronous postback which is what I use ScriptManager.RegisterClientScriptInclude for. The pain is: it does not work. The script include is somehow not executed on the client so that the javascript functions inside cannot be used. Even worse, the script block I register in ScriptManager.RegisterStartupScript does not get executed in this case! This is all very irritating. The interesting thing is that the include script and the script block do get sent to the client with the async postback (Fiddler is my friend :-)) and the script file is also loaded. But then the javascript somehow seems to break...

Does anyone have a clue or know of a reported bug?

_ScriptManager.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="_ScriptManager.aspx.cs" Inherits="Frontend.Web._Tests.ScriptManagerTest" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title></title>
  <script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js"></script>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="scm"></asp:ScriptManager>
    <asp:Label runat="server" ID="lbOut">Outside of UpdatePanel</asp:Label>
  <div style="border: solid 1px red;">
      <asp:UpdatePanel runat="server" ID="up" UpdateMode="Conditional">
        <ContentTemplate>
          <div>
            <asp:LinkButton runat="server" ID="btnFirst">Show view 1</asp:LinkButton>
            <asp:LinkButton runat="server" ID="btnSecond">Show view 2</asp:LinkButton>
          </div>
          <div>
            <asp:MultiView runat="server" ID="mv">
              <asp:View runat="server" ID="vw1">First view - static content</asp:View>
              <asp:View runat="server" ID="vw2">
                Second view - dynamically loaded content (between dashes): 
                <div>#<span id="divDyn"></span>#</div>
              </asp:View>
            </asp:MultiView>
          </div>
        </ContentTemplate>
      </asp:UpdatePanel>
  </div>
  </form>
</body>
</html>

_ScriptManager.js (here I just add some dynamic content to the span with id=divDyn):

function dynamic() {
  alert('dynamic');
  $('#divDyn').text('Dynamic!');
}

_ScriptManager.aspx.cs code-behind:

public partial class ScriptManagerTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        btnFirst.Click += delegate { mv.SetActiveView(vw1); };
        btnSecond.Click += delegate { mv.SetActiveView(vw2); };

        if (!IsPostBack)
        {
            // Test 1: does not work
            mv.SetActiveView(vw1);

            // Test 2: works, because required script is loaded on initial page request
            //mv.SetActiveView(vw2);
        }
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (mv.GetActiveView() == vw2)
        {
            // Not calling the RegisterClientScriptInclude
            // makes the alert work in both cases, but this is
            // what it's all about: including script only when
            // needed!
            ScriptManager.RegisterClientScriptInclude(
                Page, Page.GetType(), "include-js",
                ResolveClientUrl("~/ScriptManager.js"));
            ScriptManager.RegisterStartupScript(
                this, GetType(), "call-dynamic",
                "alert('hi there'); dynamic();", true);    
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九歌凝 2024-08-22 06:19:02

好吧,这太令人震惊了:经过两个 2 小时的会议调查问题,尝试了 ScriptManager 的所有可能性,尝试使用 jQuery 来代替,最后编写了这个示例(因为现实世界的设置总是更复杂),我现在发现这篇简短的博客文章解决了我的问题问题 - 在 js 文件中添加一行:

_ScriptManager.js

function dynamic() {
  alert('dynamic');
  $('#divDyn').text('Dynamic!');
}
// notify that the script has been loaded <-- new!
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

好吧,也许这对其他人来说会有用......

Well, this is shattering: after two 2h sessions of investigating the problem, trying ouf ALL of the possibilities of the ScriptManager, trying to use jQuery instead and finally writing up this sample (because the real world setup is as always more complicated), I now found this short blog post which solves my problem - with a single line added to the js file included:

_ScriptManager.js:

function dynamic() {
  alert('dynamic');
  $('#divDyn').text('Dynamic!');
}
// notify that the script has been loaded <-- new!
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Well, maybe this will be of any use for anyone else out there...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文