asp.net usercontrols中的Javascript变量 - 在同一个插入的usercontrol中覆盖变量

时间:2022-08-24 03:38:21

I have four same UserControls inserted into Default.aspx. I want to write the data into HiddenField and write this data into Label1 using javascript.

我有四个相同的UserControl插入Default.aspx。我想将数据写入HiddenField并使用javascript将此数据写入Label1。

The method only works for the last loaded UserControl - HiddenFieldLoader3.

该方法仅适用于上次加载的UserControl - HiddenFieldLoader3。

Why the method does not work in all usercontrols? How can i fix my code?

为什么该方法不适用于所有用户控件?我该如何修复我的代码?

Default.aspx

Default.aspx的

<%@ Register Src="~/HiddenFieldLoader.ascx" TagPrefix="uc1" TagName="HiddenFieldLoader" %>


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Default.aspx</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="HiddenFieldLoader.js"></script>
</head>
<body>
    <form id="form1" runat="server">
        <uc1:HiddenFieldLoader runat="server" ID="HiddenFieldLoader" />
        <uc1:HiddenFieldLoader runat="server" ID="HiddenFieldLoader1" />
        <uc1:HiddenFieldLoader runat="server" ID="HiddenFieldLoader2" />
        <uc1:HiddenFieldLoader runat="server" ID="HiddenFieldLoader3" />
    </form>
</body>
</html>

UserControl: HiddenFieldLoader.ascx

UserControl:HiddenFieldLoader.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="HiddenFieldLoader.ascx.cs" Inherits="NewControls.HiddenFieldLoader" %>

<script type="text/javascript">
    HFLoader.declareVariables("<%=Button1.ClientID %>", "<%=HiddenField1.ClientID %>", "<%=Label1.ClientID %>");
</script>

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:HiddenField ID="HiddenField1" runat="server" />

<input type="button" ID="Button1" value="Save" runat="server" />

<input type="button" ID="Button2" onclick="HFLoader.showEvent();" value="Show" runat="server" />

Javascript file: HiddenFieldLoader.js

Javascript文件:HiddenFieldLoader.js

HFLoader = {

    button: null,
    hiddenField: null,
    label: null,

    declareVariables: function (btn, hf, label) {
        HFLoader.button = btn;
        HFLoader.hiddenField = hf;
            HFLoader.label = label;
        },
        ///////SHOW EVENT
        showEvent: function () {
            $("#" + HFLoader.label).html($("#" + HFLoader.hiddenField).val());

        },
        //////!SHOW EVENT
        saveHiddenField: function (data) {

        $("#" + HFLoader.hiddenField).val(data);
    },

    buttons: function () {
        $("#" + HFLoader.button).click(function () {

            var datatest = "Data from button ID: " + $(this).attr("id");
            HFLoader.saveHiddenField(datatest);
            $("#" + HFLoader.label).html($("#" + HFLoader.hiddenField).val());
            return false;
        });
    },

    init: function () {
        $(function () {

            HFLoader.buttons();

        });
    }

};

HFLoader.init();

1 个解决方案

#1


1  

It doesn't work because you're using a single instance variable, HFLoader, and not an instance.

它不起作用,因为您使用的是单个实例变量HFLoader,而不是实例。

So one way to fix it is to wrap your HFLoader in a closer (function, local scope) so that the object is scoped per method call. In the example below, I wrapped the HFLoader variable in a creator function. Then, each call to HFLoaderCreator will produce a different version (instance) of the HFLoader object. The reason I chose to do it this way instead of creating a true JS class was because it required minimal code changes to demonstrate how it could be done.

因此,解决此问题的一种方法是将HFLoader包装在更近的(函数,本地范围)中,以便每个方法调用对象的作用域。在下面的示例中,我将HFLoader变量包装在创建者函数中。然后,每次调用HFLoaderCreator都会生成HFLoader对象的不同版本(实例)。我选择这样做而不是创建一个真正的JS类的原因是因为它需要最少的代码更改来演示如何完成它。

Edit. Let's also say you want to recall the HFLoader at a later date to call on things, such as the saveHiddenField method. To do this, I've done 2 this. 1) I've added data('HFLoader') to the three elements passed in, so you can use any one of them to recall the HFLoader settings. And 2) I've added custom events that you can trigger to call the methods. These two options show two different ways that jQuery plugin developers use to allow access to underlying structures.

编辑。我们还要说你想在以后召回HFLoader来调用事物,比如saveHiddenField方法。为此,我做了2个。 1)我已经将数据('HFLoader')添加到传入的三个元素中,因此您可以使用其中任何一个来调用HFLoader设置。 2)我添加了可以触发调用方法的自定义事件。这两个选项显示了jQuery插件开发人员用于允许访问底层结构的两种不同方式。

<script type="text/javascript">
    HFLoaderCreator("<%=Button1.ClientID %>", "<%=HiddenField1.ClientID %>", "<%=Label1.ClientID %>");
</script>


function HFLoaderCreator(btn, hf, label)
{
    var HFLoader = {

        button: null,
        hiddenField: null,
        label: null,

        declareVariables: function (btn, hf, label) {
            HFLoader.button = btn;
            HFLoader.hiddenField = hf;
            HFLoader.label = label;
        },

        saveHiddenField: function (data) {
            $("#" + HFLoader.hiddenField).val(data);
        },

        buttons: function () {
            $("#" + HFLoader.button).click(function () {

                var datatest = "Data from button ID: " + $(this).attr("id");
                HFLoader.saveHiddenField(datatest);
                $("#" + HFLoader.label).html($("#" + HFLoader.hiddenField).val());
                return false;
            });

            // add the data so it can be recalled at a later date
            $("#" + HFLoader.button).data('HFLoader', HFLoader);
            $("#" + HFLoader.hiddenField).data('HFLoader', HFLoader);
            $("#" + HFLoader.label).data('HFLoader', HFLoader);

            // add custom event handlers - saveHiddenField
            $("#" + HFLoader.button).on('saveHiddenField', HFLoader.saveHiddenField);
            $("#" + HFLoader.hiddenField).on('saveHiddenField', HFLoader.saveHiddenField);
            $("#" + HFLoader.label).on('saveHiddenField', HFLoader.saveHiddenField);

            // add custom event handlers - showEvent
            $("#" + HFLoader.button).on('showEvent', HFLoader.showEvent);
            $("#" + HFLoader.hiddenField).on('showEvent', HFLoader.showEvent);
            $("#" + HFLoader.label).on('showEvent', HFLoader.showEvent);  
        },

        init: function () {
            $(function () {

                HFLoader.buttons();

            });
        }

    };

   HFLoader.declareVariables(btn, hf, label);
   HFLoader.init();

   return HFLoader;
}

So now to make use of it all. In JS, if you wanted to look up the HFLoader data based on the Button1 ID, you might do something like this:

所以现在要充分利用它。在JS中,如果你想根据Button1 ID查找HFLoader数据,你可能会这样做:

<script type="text/javascript">
  var HFLoader = $('#<%=Button1.ClientID %>').data('HFLoader');
  HFLoader.showEvent();
</script>

If you wanted to use ButtonID1 to trigger the custom event, which would ultimately call the showEvent method, you could do:

如果您想使用ButtonID1来触发最终调用showEvent方法的自定义事件,您可以执行以下操作:

<script type="text/javascript">
  $('#<%=Button1.ClientID %>').trigger('showEvent');
</script>

And if you wanted to do it inline, like your first example...

如果你想内联,就像你的第一个例子......

<input type="button" ID="Button2" onclick="$('#<%=Button1.ClientID %>').data('HFLoader').showEvent();" value="Show" />

Although I'd highly recommend instead using JS to wire an event to Button2, such as:

虽然我强烈建议使用JS将事件连接到Button2,例如:

$(function()
{
  $('#<%=Button2.ClientID').click(function()
  {
    $('#<%=Button1.ClientID %>').data('HFLoader').showEvent();

    return false;
  });
});

That way it's not inline script. Overall, the script for HFLoader is a bit hacked together. I'd recommend taking a look at the examples I've put together to extract the pieces of useful information and consider rethinking and/or rewriting the way you're doing things. Your brain is pushing you towards some kind of "global" view, or some kind of automatically scoped variable called HFLoader. But if you have 5 instances on a page, then you really want instances of some HFLoader object and not some global concept of HFLoader. It's like creating a new instance of a class instead of using a static or singleton instance of a class -- two very different concepts!

这样它不是内联脚本。总的来说,HFLoader的脚本有点被黑了。我建议你看一下我汇总的例子来提取有用的信息,并考虑重新思考和/或重写你做事的方式。你的大脑正在推动你走向某种“全局”视图,或某种自动范围变量称为HFLoader。但是如果你在一个页面上有5个实例,那么你真的想要一些HFLoader对象的实例,而不是HFLoader的一些全局概念。这就像创建一个类的新实例而不是使用类的静态或单例实例 - 两个非常不同的概念!

I hope this helps.

我希望这有帮助。

#1


1  

It doesn't work because you're using a single instance variable, HFLoader, and not an instance.

它不起作用,因为您使用的是单个实例变量HFLoader,而不是实例。

So one way to fix it is to wrap your HFLoader in a closer (function, local scope) so that the object is scoped per method call. In the example below, I wrapped the HFLoader variable in a creator function. Then, each call to HFLoaderCreator will produce a different version (instance) of the HFLoader object. The reason I chose to do it this way instead of creating a true JS class was because it required minimal code changes to demonstrate how it could be done.

因此,解决此问题的一种方法是将HFLoader包装在更近的(函数,本地范围)中,以便每个方法调用对象的作用域。在下面的示例中,我将HFLoader变量包装在创建者函数中。然后,每次调用HFLoaderCreator都会生成HFLoader对象的不同版本(实例)。我选择这样做而不是创建一个真正的JS类的原因是因为它需要最少的代码更改来演示如何完成它。

Edit. Let's also say you want to recall the HFLoader at a later date to call on things, such as the saveHiddenField method. To do this, I've done 2 this. 1) I've added data('HFLoader') to the three elements passed in, so you can use any one of them to recall the HFLoader settings. And 2) I've added custom events that you can trigger to call the methods. These two options show two different ways that jQuery plugin developers use to allow access to underlying structures.

编辑。我们还要说你想在以后召回HFLoader来调用事物,比如saveHiddenField方法。为此,我做了2个。 1)我已经将数据('HFLoader')添加到传入的三个元素中,因此您可以使用其中任何一个来调用HFLoader设置。 2)我添加了可以触发调用方法的自定义事件。这两个选项显示了jQuery插件开发人员用于允许访问底层结构的两种不同方式。

<script type="text/javascript">
    HFLoaderCreator("<%=Button1.ClientID %>", "<%=HiddenField1.ClientID %>", "<%=Label1.ClientID %>");
</script>


function HFLoaderCreator(btn, hf, label)
{
    var HFLoader = {

        button: null,
        hiddenField: null,
        label: null,

        declareVariables: function (btn, hf, label) {
            HFLoader.button = btn;
            HFLoader.hiddenField = hf;
            HFLoader.label = label;
        },

        saveHiddenField: function (data) {
            $("#" + HFLoader.hiddenField).val(data);
        },

        buttons: function () {
            $("#" + HFLoader.button).click(function () {

                var datatest = "Data from button ID: " + $(this).attr("id");
                HFLoader.saveHiddenField(datatest);
                $("#" + HFLoader.label).html($("#" + HFLoader.hiddenField).val());
                return false;
            });

            // add the data so it can be recalled at a later date
            $("#" + HFLoader.button).data('HFLoader', HFLoader);
            $("#" + HFLoader.hiddenField).data('HFLoader', HFLoader);
            $("#" + HFLoader.label).data('HFLoader', HFLoader);

            // add custom event handlers - saveHiddenField
            $("#" + HFLoader.button).on('saveHiddenField', HFLoader.saveHiddenField);
            $("#" + HFLoader.hiddenField).on('saveHiddenField', HFLoader.saveHiddenField);
            $("#" + HFLoader.label).on('saveHiddenField', HFLoader.saveHiddenField);

            // add custom event handlers - showEvent
            $("#" + HFLoader.button).on('showEvent', HFLoader.showEvent);
            $("#" + HFLoader.hiddenField).on('showEvent', HFLoader.showEvent);
            $("#" + HFLoader.label).on('showEvent', HFLoader.showEvent);  
        },

        init: function () {
            $(function () {

                HFLoader.buttons();

            });
        }

    };

   HFLoader.declareVariables(btn, hf, label);
   HFLoader.init();

   return HFLoader;
}

So now to make use of it all. In JS, if you wanted to look up the HFLoader data based on the Button1 ID, you might do something like this:

所以现在要充分利用它。在JS中,如果你想根据Button1 ID查找HFLoader数据,你可能会这样做:

<script type="text/javascript">
  var HFLoader = $('#<%=Button1.ClientID %>').data('HFLoader');
  HFLoader.showEvent();
</script>

If you wanted to use ButtonID1 to trigger the custom event, which would ultimately call the showEvent method, you could do:

如果您想使用ButtonID1来触发最终调用showEvent方法的自定义事件,您可以执行以下操作:

<script type="text/javascript">
  $('#<%=Button1.ClientID %>').trigger('showEvent');
</script>

And if you wanted to do it inline, like your first example...

如果你想内联,就像你的第一个例子......

<input type="button" ID="Button2" onclick="$('#<%=Button1.ClientID %>').data('HFLoader').showEvent();" value="Show" />

Although I'd highly recommend instead using JS to wire an event to Button2, such as:

虽然我强烈建议使用JS将事件连接到Button2,例如:

$(function()
{
  $('#<%=Button2.ClientID').click(function()
  {
    $('#<%=Button1.ClientID %>').data('HFLoader').showEvent();

    return false;
  });
});

That way it's not inline script. Overall, the script for HFLoader is a bit hacked together. I'd recommend taking a look at the examples I've put together to extract the pieces of useful information and consider rethinking and/or rewriting the way you're doing things. Your brain is pushing you towards some kind of "global" view, or some kind of automatically scoped variable called HFLoader. But if you have 5 instances on a page, then you really want instances of some HFLoader object and not some global concept of HFLoader. It's like creating a new instance of a class instead of using a static or singleton instance of a class -- two very different concepts!

这样它不是内联脚本。总的来说,HFLoader的脚本有点被黑了。我建议你看一下我汇总的例子来提取有用的信息,并考虑重新思考和/或重写你做事的方式。你的大脑正在推动你走向某种“全局”视图,或某种自动范围变量称为HFLoader。但是如果你在一个页面上有5个实例,那么你真的想要一些HFLoader对象的实例,而不是HFLoader的一些全局概念。这就像创建一个类的新实例而不是使用类的静态或单例实例 - 两个非常不同的概念!

I hope this helps.

我希望这有帮助。