【发布时间】:2010-10-23 17:12:51
【问题描述】:
您在网上找到的大多数使用 ASP.NET 页面中的 javascript 的示例都将 javascript 放在标记文件 (*.aspx) 中。这当然是一个非常糟糕的主意(tm),除了最简单的 javascript 用途。
当然,我们想要的是将 javascript 封装到一个类中,并实例化该类的一个实例并将其绑定到代码隐藏。
Microsoft 在其 IScriptControl 接口中为用户控件和服务器控件提供了执行此操作的框架。这允许开发人员创建一个 javascript“组件”——在 *.js 文件中定义一个 javascript 类,在包含控件的页面上包含 *.js 文件,实例化组件的实例,设置变量从代码隐藏中的值在组件中,并在客户端的 javascript 中获取对组件的引用。
问题是 - IScriptControl 仅适用于用户和服务器控件。它不能用于在页面级别实例化 javascript 对象。
那么 - 人们是如何做到这一点的?我们有一些我们一直在使用的模式,似乎很有效。我想知道每个人对它们的看法,以及其他人在使用什么。
我们首先在 *.js 文件中定义一个 javascript 类。在代码隐藏中,我们创建了一个 loadJavascript() 函数,我们在初始加载或完整回发(但不是部分回发)时从 Page_Load 调用该函数。
在 loadJavascript() 中,我们将 *.js 文件包含在 ScriptManager.RegisterClientScriptInclude() 中,然后构造一些 javascript 来实例化类的实例,分配对已知名称的引用,并注册对象的初始化() 和 dispose() 方法作为 window.load 和 window.unload 的处理程序。
例如:
string url = this.ResolveUrl("./FooBar.js");
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), url, url);
string script = @"
if (typeof {0}_obj == 'undefined')
{0}_obj = {{}};
{0}_obj.fooBar = new FooBar();
Sys.UI.DomEvent.addHandler(window, 'load',
function()
{{
{0}_obj.fooBar.initialize('{1}', '{2}');
}}
);
Sys.UI.DomEvent.addHandler(window, 'unload', {0}_obj.fooBar.dispose);
";
script = String.Format(script,
new object[]
{
this.ClientID,
this.foo.ClientID,
this.bar.ClientID
});
ScriptManager.RegisterStartupScript(
this, this.GetType(), this.ClientID, script, true);
如果我们还没有的话,我们会根据页面的 ClientID 在全局命名空间中构造一个对象名称。我们将新类的一个实例添加为全局对象的成员。我们添加一个调用对象的 intialize() 方法的 window.load 处理程序,传递对象方法需要访问的页面上控件的 clientID。我们添加了一个 window.unload 处理程序,它调用我们对象的 dispose() 方法,它会执行任何必要的清理工作。
这似乎对我们有用。我们已经在许多页面上使用了这种模式,其中一些页面进行了大量的部分回发,没有任何问题。
首先,我想知道人们对这种模式的看法。
但更重要的是,我想知道我们是否一直在重新发明轮子,以及是否有其他方法来处理我们正在解决的问题,而我们不知道。
谁有更好的想法?
【问题讨论】:
-
一个页面就是一个控件,为什么不能使用常规框架呢?
-
不,我没有。但是,鉴于 Page 继承自 Control,从您的描述中不清楚为什么不能在 Page 上使用它。我从您的评论中猜测它不起作用(或不容易起作用)?
-
我试过了,遇到了问题,然后去寻找另一种方法。现在很可能是我做错了什么。如果有人能告诉我它可以工作,我一定会重新审视它。或者,如果有人有另一种方法来在 ASP.NET 中实例化 javascript 类的实例,我很想听听。
标签: javascript asp.net