pri*_*bel 27 javascript architecture web-applications
我有一个问题,不容易描述.我正在编写一个强大的jQuery和AJAX调用的Web应用程序.现在我在Javascript archicture中没有很多经验,但我意识到我的程序没有很好的结构.我认为我有太多的标识符指的是同一个(至少或多或少)的东西.
让我们看看构成应用程序的一小部分的任意示例性UI小部件:小部件可以是窗口的一部分,窗口可以是窗口管理器的一部分:
现在我有不同的四个不同的对象标识符用于相同的事情,需要保持同步,直到页面重新加载.这似乎不是一件好事.
编辑:
@Will Morgan:它是一个表单设计器,允许在浏览器中创建Web表单.后端是Zope,一个python Web应用程序服务器.很难更明确,因为这是我在使用trio jQuery,DOM树和我自己的原型类实例进行Javasscript开发时一直观察到的一般问题.
EDIT2:
我认为做一个例子虽然是一个人为的例子会有所帮助.下面您将看到一个记录器小部件,可用于将块元素添加到显示已记录项目的网页.
makeLogger = function(){
var rootEl = document.createElement('div');
rootEl.innerHTML = 'Logged items:';
rootEl.setAttribute('class', 'logger');
var append = function(msg){
// append msg as a child of root element.
var msgEl = document.createElement('div');
msgEl.innerHTML = msg;
rootEl.appendChild(msgEl);
};
return {
getRootEl: function() {return rootEl;},
log : function(msg) {append(msg);}
};
};
// Usage
var logger = makeLogger();
var foo = document.getElementById('foo');
foo.appendChild(logger.getRootEl());
logger.log('What\'s up?');
Run Code Online (Sandbox Code Playgroud)
此时,我有一个围绕HTMLDivElement(托管对象)的包装器.有了logger实例(本机对象),我可以通过函数logger.getRootEl()轻松地使用它.
我遇到困难的地方是我手头只有DOM元素,需要对函数makeLogger返回的公共API做一些事情(例如在事件处理程序中).而这就是混乱开始的地方.我需要将所有本机对象保存在存储库或其他东西中,以便我可以再次检索.从托管对象到我的本机对象的连接(例如对象属性)会更好.我知道可以做到,但它有一些缺点:
现在,我使用jQuery的data()方法进行后引用.但总而言之,我不喜欢跟踪托管对象与其原生对象之间关系的方式.
EDIT3:
经过一些见解后,我从Anurag的例子中
获益 .. @Anurag:如果我理解你的例子是正确的,关键点是设置正确的(正确的取决于你的需要)事件的执行上下文处理程序.在您的情况下,这是使用Mootool的bind()函数完成的表示对象实例.因此,您确保始终处理包装器对象(我称之为本机对象)而不是DOM对象,对吧?
给读者的一个注释:你没有被迫使用Mootools来达到这个目的.在jQuery中,您可以使用$ .proxy()函数设置事件处理程序,或者如果您使用普通的旧Javascript,则可以使用每个函数公开的apply属性.
您可以使用全局注册表:
window.WidgetRegistry = {};
window.WidgetRegistry['foowidget'] = new Widget('#myID');
Run Code Online (Sandbox Code Playgroud)
当AJAX调用返回时,他们可以像这样获取小部件:
var widgetID = data.widgetID;
if (widgetID in window.WidgetRegistry) {
var widget = window.WidgetRegistry[widgetID];
}
Run Code Online (Sandbox Code Playgroud)
对于你的jQuery调用:我猜他们相对便宜,因为jQuery缓存对象供以后使用.但你可以WidgetRegistry通过使用扩展以上建议.data():
var $widget = $('#myWidget');
var widgetID = 'foo';
$widget.data('widget', widgetID);
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以存储附加到每个jQuery对象的窗口小部件ID,并从全局注册表重新访问它.
测试,如果jQuery对象具有现有小部件:
return $('#test').data('widget') &&
($('#test').data('widget') in window.WidgetRegistry);
Run Code Online (Sandbox Code Playgroud)
请注意,这些只是建议.实际上,有很多方法可以实现这样的整合.如果你想将你的代码与jQuery更深层地结合起来,你可以扩展jQuery对象,这样你就可以编写如下内容:
$('#widget').widget({'foo':'bar'});
// and/or
var allWidgets = $('*:widget');
// ...
Run Code Online (Sandbox Code Playgroud)