如何覆盖由Asp.Net UpdatePanel添加(动态)的Javascript函数?

Rod*_*ira 5 javascript asp.net

我在只能想象是Javascript范围问题和Microsoft Asp.Net客户端框架方面遇到了一些麻烦。

由于此问题中所述的原因,我需要覆盖由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>
Run Code Online (Sandbox Code Playgroud)

现在,当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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

问题是,此链接由asp.net框架放置在head标签中。

即使我的函数仍在原始函数的下面进行分层定义,也不会调用我的函数。

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

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

在此先感谢您抽出宝贵的时间。

Rod*_*ira 2

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

基本上,我创建的代码将在页面首次加载时定义我的函数。另外,我注册了自定义函数,以便在每次 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

实用工具.js

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

完成此操作后,我的代码适用于所有使用 MasterPage 的页面。该代码将不断地用我的代码覆盖验证函数。有一点开销,但我想不出其他方法。