如何在复杂的Web应用程序中构建JavaScript程序的结构?

15 浏览
0 Comments

如何在复杂的Web应用程序中构建JavaScript程序的结构?

我有一个问题,很难描述。我正在编写一个使用jQuery和AJAX调用的Web应用程序。现在我在Javascript架构方面没有太多经验,但我意识到我的程序结构不好。我认为我有太多引用相同(至少多多少少)东西的标识符。

让我们看一个任意的示例UI小部件,它构成了应用程序的一小部分:该小部件可能是一个窗口的一部分,而该窗口可能是一个窗口管理器的一部分:

  1. 事件处理程序使用DOM元素作为参数。DOM元素表示浏览器中的小部件。
  2. 很多时候,我使用jQuery对象(基本上是DOM元素的包装器)来对小部件进行操作。有时它们是短暂使用的,有时它们被存储在变量中以备后用。
  3. AJAX函数调用使用字符串标识符来标识这些小部件。它们在服务器端进行处理。
  4. 此外,我还有一个小部件类,其实例表示一个小部件。它通过new运算符进行实例化。

现在,我对于同一个东西有四个不同的对象标识符,需要在页面重新加载之前保持同步。这似乎不是一件好事。

有什么建议吗?

编辑:

*@Will Morgan*:这是一个允许在浏览器中创建Web表单的表单设计器。后端是Zope,一个Python Web应用程序服务器。由于这是一个使用jQuery、DOM树和我的自定义原型类实例进行JavaScript开发时经常遇到的一般性问题,很难更加明确。

编辑2:

我认为提供一个例子会有所帮助,尽管它是一个人为的例子。下面是一个可以用于在Web页面中添加一个块元素以显示日志项的日志小部件。

makeLogger = function(){
     var rootEl = document.createElement('div');
     rootEl.innerHTML = 'Logged items:';
     rootEl.setAttribute('class', 'logger');
     var append = function(msg){
           // 将msg作为根元素的子元素附加。
           var msgEl = document.createElement('div');
           msgEl.innerHTML = msg;
           rootEl.appendChild(msgEl);
     };
     return {
          getRootEl: function() {return rootEl;},
          log      : function(msg) {append(msg);}
     };
};
// 使用
var logger = makeLogger();
var foo = document.getElementById('foo');
foo.appendChild(logger.getRootEl());
logger.log('What\'s up?');

此时,我有一个HTMLDivElement的封装器(托管对象)。有了logger实例(本机对象),我可以通过函数logger.getRootEl()轻松地使用它。

当我只有DOM元素并且需要使用函数makeLogger返回的公共API执行某些操作时,我会陷入困境(例如,在事件处理程序中)。这就是混乱开始的地方。我需要将所有本机对象存储在一个仓库中,以便以后可以检索。如果能够有一个从托管对象返回到本机对象的连接(例如,一个对象属性),那将会更好。

我知道这是可以做到的,但它有一些缺点:

  • 这种(循环)引用可能会导致内存泄漏,尤其是在IE7中
  • 什么时候传递托管对象,什么时候传递本机对象(在函数中)?

目前,我使用jQuery的data()方法进行反向引用。但总体而言,我不喜欢在托管对象与其本机对应物之间保持关系的方式。

您如何处理这种情况?

编辑3:

从Anurag的例子中,我获得了一些见解..

*@Anurag*:如果我正确理解你的例子,关键点是为事件处理程序设置正确(根据你的需求而定)的执行上下文。在你的情况下,这是演示对象实例,它是通过Mootool的bind()函数完成的。所以你确保始终处理包装对象(我称之为本机对象),而不是DOM对象,对吗?

读者请注意:您不必使用Mootools来实现这一点。在jQuery中,您可以使用*$.proxy()*函数设置事件处理程序,或者如果您使用的是普通的Javascript,您可以利用每个函数都公开的*apply*属性。

0