多个用户控件和JavaScript

6

我在用户控件中包含了一个JS文件。主机页面有多个用户控件实例。

JS文件有一个全局变量,用作JS函数的标记。我需要将此变量的作用范围限制在用户控件内。不幸的是,当我有多个控件实例时,变量值会被覆盖。

在这种情况下,推荐采取什么方法?

4个回答

5
一些选项是根据用户控件的ClientId动态生成javascript。例如,您可以动态生成全局变量。
另一个选项(我建议使用)是将全局变量和函数封装在对象中,然后您的用户控件可以发出JS以创建该对象的实例(可以动态命名,从而让您自由地确定对象的范围)。
编辑:
我没有一个可分享的工作代码示例,但我已经用几种不同的方式实现了这个功能。最简单的方法是在用户控件的标记中执行此操作。
<script language='javascript'>
   var <%=this.ClientID%>myObject=new myObject();
</script>

假设你的控件clientId为myControl,这将创建一个名为myControlmyObject的变量。
另一种方法是在代码后端生成脚本,然后使用以下命令进行注册:Page.ClientScript.RegisterStartupScript()

Josh - 我喜欢你推荐的方法。你有代码示例吗? - Bob Smith
@Bob:请查看我的回复,其中包含一个代码示例,展示如何将变量封装在对象中。 - Ryan Shripat
Josh - 这是我理解的应该做的事情:
  1. 在JS中创建一个包含所有UC共享函数的类
  2. 根据你的代码片段创建一个类的实例
  3. 如果我使用myControlmyObject.FunctionA()调用JS函数,那么作用域是否会限制在UC内?
- Bob Smith
这个解决方案是基于 JavaScript 多态的概念吗? - Bob Smith
不,它基本上只是一个对象,你只需要在全局命名空间中具有多个唯一命名的实例。 - JoshBerke

2

如果你必须继续使用当前的解决方案,你可以将全局变量重命名为以下代码中的内容,该代码应该在控件的 .ascx 文件中:

<script type='text/javascript'>
var <%= this.ClientID %>_name_of_global_variable;
</script>

在这里,“this”是指asp.net控件。这样,每个控件都有一个基于客户端id的唯一变量名。确保更新您的其余javascript以使用此新命名约定。问题是,它看起来很混乱,并且变量名将根据控件嵌入页面的位置而变得非常长。

明白了吗?只需要进行最少的javascript修改即可使其正常工作。


JS代码在一个单独的文件中,我无法使用<%= %>来注入客户端ID。 - Bob Smith
如果您在代码后端为该控件注册JavaScript,则概念可以保持不变。 - Carl
(在代码后端仅注册全局变量的声明) - Carl

2

我建议你重构你的代码,将所有通用的JS逻辑放在一个地方,而不是在每个用户控件中。这将大大减少页面的大小。

你可以向通用JS方法传递UserControl的id来区分UserControl。

对于限制“UserControl”变量范围的问题,你可以存储一些键/值结构来保留你特定于用户控件的值 - 键将是用户控件客户端ID,而值将是你感兴趣的变量。

例如:

var UCFlags = new Object();
//set the flag for UserControl1:
UCFlags["UC1"] = true;
//set the flag for UserControl2:
UCFlags["UC2"] = false;

要访问它们,您只需将UserControl的ClientID传递到UCFlags数组中即可:
myFlag = UCFlags["UC1"];

在服务器端,您可以将常量字符串“UC1”或“UC2”替换为

<%= this.ClientID %>

像这样:

myFlag = UCFlags["<%= this.ClientID %>"];

即使大部分JS代码在单独的文件中,您仍然可以在此处使用“<%= this.ClientID %>”语法;只需设置。
UCFlags["<%= this.ClientID %>"] = value;

在调用JS文件之前。

Ryan - 我可以在页面上拥有任意数量的用户控件。因此,我无法确定性地创建UCFlags数组。UCFlags ["UC1"] = true; UCFlags ["UC2"] = false; .. .. .. UCFlags ["UCn"] = false; - Bob Smith
@Bob:我明白,但是使用这种方法,您不需要知道有多少UC,只需说UCFlags["<%= this.ClientID %>"] = true就会在UCFlags对象上创建一个属性(点ClientID),并将值初始化为“true”。 - Ryan Shripat
啊,我看到你在 JavaScript 中使用哈希表了。第一次看起来像数组 :) 谢谢。 - Bob Smith
在JS中,它被称为“关联数组”-请查看此链接:http://www.quirksmode.org/js/associative.html - Ryan Shripat

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接