从ASP.NET页面实例化javascript对象

时间:2010-10-18 17:57:29

标签: javascript asp.net

您在网上找到的大多数使用ASP.NET页面中的javascript的示例都会将javascript放入标记文件(* .aspx)中。当然,除了最简单的javascript使用之外,这是一个非常糟糕的主意(tm)。

我们想要的当然是将javascript包装到一个类中,并实例化该类的实例并将其绑定到代码隐藏。

Microsoft在其IScriptControl接口中为用户控件和服务器控件提供了一个框架。这允许开发人员创建一个javascript“组件” - 在* .js文件中定义javascript类,在包含控件的页面上包含* .js文件,实例化组件的实例,设置变量在代码隐藏中的值的组件中,并在客户端的javascript中获取对组件的引用。

问题是 - IScriptControl仅适用于用户和服务器控件。它不能用于在页面级别实例化javascript对象。

那么 - 人们如何做到这一点?我们有一些模式,我们一直在使用,似乎工作。我想知道每个人都想到了什么,以及其他人在使用什么。

我们首先在* .js文件中定义一个javascript类。在代码隐藏中,我们创建了一个loadJavascript()函数,我们在初始加载或完全回发时调用Page_Load(但不是部分回发)。

在loadJavascript()中,我们使用ScriptManager.RegisterClientScriptInclude()包含* .js文件,然后构造一些javascript来实例化类的实例,分配对已知名称的引用,并注册对象的初始化()和dispose()方法作为window.load和window.unload的处理程序。

E.g:

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在全局命名空间中构造一个对象名。我们将新类的实例添加为全局对象的成员。我们添加一个window.load处理程序,它调用对象的intialize()方法,在对象的方法需要访问的页面上传递控件的clientID。我们添加一个window.unload处理程序,它调用我们对象的dispose()方法,该方法执行必要的清理工作。

这似乎对我们有用。我们在很多页面上使用过这种模式,其中一些页面做了大量的部分回发,没有任何问题。

首先,我想知道人们对这种模式的看法。

但更重要的是,我想知道我们是否一直在重新发明轮子,以及是否有其他方法来处理我们正在解决的问题,我们并不知道。

任何人都有更好的想法吗?

1 个答案:

答案 0 :(得分:0)

  

但更重要的是,我想知道我们是否一直在重新发明轮子,以及是否有其他方法来处理我们正在解决的问题,我们并不知道。

我认为这是最好的方法,我在几年前使用相同的方式解决了非常复杂的javascript代码中的任何问题。我不明白你为什么质疑自己:)

这个想法是你跟随的,现在也许有一些变化,也许我没有称之为卸载,虚空创建一个对象来保持foobar并且直接调用foobar,但这个想法是一样的。我还检查Javascript文件是否已加载......

string script = @"
    if (typeof (FooBar) != "undefined") {{
        var {0}fooBar = new FooBar();
        Sys.UI.DomEvent.addHandler(window, 'load', 
            function()
            {{
                {0}fooBar.initialize('{1}', '{2}');
            }}
        );
    }}