【问题标题】:How do I overwrite a Javascript function added (dynamically) by Asp.Net UpdatePanel?如何覆盖由 Asp.Net UpdatePanel(动态)添加的 Javascript 函数?
【发布时间】:2013-12-05 23:26:41
【问题描述】:

我只能想象 Javascript 范围问题与 Microsoft Asp.Net 客户端框架一起出现问题。

由于this question 中所述的原因,我需要覆盖由 Asp.Net 的 ScriptResource.axd 提供服务并由其 Validator 服务器控件使用的 javascript 函数 ValidatorConvert。

首先,我将介绍如何使代码正常工作。然后我会展示一个我无法让它工作的场景。

这是一个带有验证器控件的简单 Asp.Net WebForm:

<body>
<form id="form1" runat="server">
    <script type="text/javascript">
        function ValidatorConvert(op, dataType, val) {
            //>>Overwrite ValidatorConvert function.
            //>>Call to the original JS file will be below the form tag and above script tag
            return op.toString(); //<<Consider everything as valid (client side)
        }
    </script>
    <asp:ScriptManager runat="server"
        ID="Scriptmanager1" 
        allowcustomerrorsredirect="true" 
        asyncpostbackerrormessage="Operation cannot be executed."
        asyncpostbacktimeout="90"
        enablepartialrendering="true"
        enablescriptglobalization="true" 
        enablescriptlocalization="true" 
        supportspartialrendering="true" 
        scriptmode="Inherit"></asp:ScriptManager>
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:CompareValidator
        ID="CompareValidator1"
        runat="server"
        ErrorMessage="Ops, not an integer"
        Operator="DataTypeCheck"
        Type="Integer"
        ControlToValidate="TextBox1"></asp:CompareValidator>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</form>
</body>

现在,当 asp.net 呈现表单时,它会以某种方式检测到页面上有一个可见的验证器控件。因此,将在表单下方和我的脚本标签上方调用客户端 JS 验证器。这个 JS 文件会有一个 ValidatorConvert 函数,它会被我的覆盖。

现在,这是一个不起作用的场景。这是一个稍微不同的 WebForm:

<body>
<form id="form1" runat="server">
    <asp:ScriptManager runat="server"
        ID="Scriptmanager1" 
        allowcustomerrorsredirect="true" 
        asyncpostbackerrormessage="Operation cannot be executed."
        asyncpostbacktimeout="90"
        enablepartialrendering="true"
        enablescriptglobalization="true" 
        enablescriptlocalization="true" 
        supportspartialrendering="true" 
        scriptmode="Inherit"></asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
                <asp:View ID="View1" runat="server">
                    <asp:Button ID="ButtonShowInput" runat="server" Text="Show Input     Field" CausesValidation="false" OnClick="ButtonShowInput_Click" />
                </asp:View>
                <asp:View ID="View2" runat="server">
                    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                    <asp:CompareValidator
                        ID="CompareValidator1"
                        runat="server"
                        ErrorMessage="Ops, not an integer"
                        Operator="DataTypeCheck"
                        Type="Integer"
                        ControlToValidate="TextBox1"></asp:CompareValidator>
                    <asp:Button ID="Button1" runat="server" Text="Button"   OnClick="Button1_Click" />
                </asp:View>
            </asp:MultiView>
        </ContentTemplate>
    </asp:UpdatePanel>
</form>
</body>

现在我在 UpdatePanel 中有一个 MultiView。页面加载时可见的视图是第一个只有一个按钮的视图。按下此按钮时,它将显示带有验证器控件的第二个视图。因为这是在 UpdateUpdate 中,所以这将使用 AJAX 完成。

现在,当呈现表单时,默认情况下验证器控件是不可见的。因此,指向 javascript 文件 (ScriptResource.axd) 的链接根本不会放在页面上!

但是当按下按钮并且验证器可见时,链接将被动态添加。

问题是,这个链接是asp.net框架放在head标签里的。

即使我的函数仍按层次定义在原始函数之下,我的函数也不会被调用。

我尝试将我的函数放在不同的位置,包括 head 标签,但它似乎也不起作用。似乎它被认为是最后定义的函数。

那么,如何在第二种情况下覆盖该函数?此外,是否有适用于这两种情况的单一解决方案?

提前感谢您抽出宝贵时间。

【问题讨论】:

  • 您是否尝试在单击按钮时通过ScriptManager.RegisterStartupScriptScriptManager.RegisterClientScriptBlock 在服务器端代码中以编程方式生成该JS 函数?
  • 尤里,感谢您的意见。 RegisterClientScriptBlock 没有帮助。但是,在测试您的建议时,我尝试将脚本块放在 UpdatePanel 中。不知何故,这成功了。 Id 与标签在 UpdatePanel 内的哪个位置无关。我仍在调查此事以了解其背后的原因。但我想最终我可以有一个 MasterPage 定义我的函数“OnPageReady”,然后在 Ajax 执行后尝试设置它。这可能对单个应用程序的两种情况都有效。稍后我会在这里测试并发布。谢谢。
  • 酷,很高兴您找到了解决方案。祝你好运!

标签: javascript asp.net


【解决方案1】:

感谢 Yuriy 的意见,我能够想出一个解决方案。

基本上,我创建的代码将在页面首次加载时定义我的函数。此外,我注册了我的自定义函数以在每次 ajax 请求后重新定义我的函数。鉴于我将此代码放在 MasterPage 上,我能够使其在所有应用程序中运行。

代码如下:

MasterPage.aspx 是一个简单的 Html 页面,其 ContentPlaceHolders 和 ScriptManager 位于表单标记的正下方。此外,我必须在页面顶部(head 标签)放置对我的“Utils.js”的引用。

MasterPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        if (!Page.ClientScript.IsStartupScriptRegistered("jsDefineFunction"))
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "jsDefineFunction", "defineValidationFunction();", true);

        if (!Page.ClientScript.IsStartupScriptRegistered("jsDefineEndRequestFunction"))
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "jsDefineEndRequestFunction", "Sys.WebForms.PageRequestManager.getInstance().add_endRequest(defineValidationFunction);", true);
    }
}

Utils.js

function defineValidationFunction() {
    var ValidatorConvert = function (op, dataType, val) {
            //>>Consider everything as valid (client side)
            return op.toString();
        }
}

有了这些,我的代码适用于所有使用 MasterPage 的页面。该代码将不断用我的代码覆盖验证功能。有一点开销,但我想不出另一种方法。

【讨论】:

    猜你喜欢
    • 2017-03-02
    • 1970-01-01
    • 2016-10-07
    • 2011-07-21
    • 1970-01-01
    • 2010-10-07
    • 2014-08-27
    • 2010-10-30
    相关资源
    最近更新 更多