对象字面处理多个实例
问题描述:
我的整个JavaScript库都是在对象字面命名空间中构造的。它包含了从init()到常用函数,控件,验证等的每个页面的逻辑。页面的init()函数根据页面的body ID被触发。对象字面处理多个实例
我的问题是在我的控制部分。我有一个名为AddressEntry的对象文字。此对象文字包含处理我的AddressEntry ASP.NET UserControl的功能。在页面上使用一个AddressEntry控件时,它可以正常工作,但如果有多个,则只有页面上的最后一个按预期工作。
这里是我的AddressEntry对象常量(下调到相关信息):
SFAIC.ctrls.AddressEntry = {
inputs : {
city : undefined,
cityState : undefined,
hidden : {
city : undefined,
state : undefined
},
},
fn : {
root : undefined,
citySelected : function($ddl) {
var $selected = $ddl.find(":selected");
this.root.inputs.hidden.city.val($selected.val());
this.root.inputs.hidden.state.val($selected.text().split(", ")[1]);
}
},
init : function(addressId) {
var self = this,
fn = self.fn,
inputs = self.inputs,
hidden = inputs.hidden;
inputs.city = SFAIC.fn.getContentElement(addressId + "_ddlCity", SFAIC.$updatePanel);
inputs.cityState = SFAIC.fn.getContentElement(addressId + "_ddlCityStateLocked", SFAIC.$updatePanel);
hidden.city = SFAIC.fn.getContentElement(addressId + "_txtCity", SFAIC.$updatePanel);
hidden.state = SFAIC.fn.getContentElement(addressId + "_txtState", SFAIC.$updatePanel);
fn.root = this;
inputs.city.change(function() { fn.citySelected($(this)); });
inputs.cityState.change(function() { fn.citySelected($(this)); });
}
};
然后,页面对象字面会是这个样子(再次下调):
SFAIC.pages.salesProcess.Applicant = {
init : function() {
SFAIC.ctrls.AddressEntry.init("AddressGarage");
SFAIC.ctrls.AddressEntry.init("AddressMailing");
}
};
对我来说很明显AddressMailing init覆盖了AddressGarage init。我能做些什么来将对象化为:我可以在页面上处理尽可能多的AddressEntry UserControls,而不会互相覆盖对象,从而使对象字面量化?
答
这是我想出了解决方案:
SFAIC.ctrls.AddressEntry = function(addressId) {
var ctrl = {
inputs : {
city : undefined,
cityState : undefined,
hidden : {
city : undefined,
state : undefined
},
},
fn : {
root : undefined,
citySelected : function($ddl) {
var $selected = $ddl.find(":selected");
this.root.inputs.hidden.city.val($selected.val());
this.root.inputs.hidden.state.val($selected.text().split(", ")[1]);
}
},
init : function(addressId) {
var self = this,
fn = self.fn,
inputs = self.inputs,
hidden = inputs.hidden;
inputs.city = SFAIC.fn.getContentElement(addressId + "_ddlCity", SFAIC.$updatePanel);
inputs.cityState = SFAIC.fn.getContentElement(addressId + "_ddlCityStateLocked", SFAIC.$updatePanel);
hidden.city = SFAIC.fn.getContentElement(addressId + "_txtCity", SFAIC.$updatePanel);
hidden.state = SFAIC.fn.getContentElement(addressId + "_txtState", SFAIC.$updatePanel);
fn.root = this;
inputs.city.change(function() { fn.citySelected($(this)); });
inputs.cityState.change(function() { fn.citySelected($(this)); });
}
};
ctrl.init();
return ctrl;
};
SFAIC.pages.salesProcess.Applicant = {
init : function() {
var garage, mailing;
garage = SFAIC.ctrls.AddressEntry("AddressGarage");
mailing = SFAIC.ctrls.AddressEntry("AddressMailing");
}
};
答
对象字面量根据定义是对象的单个实例。也许你应该用原型创建一个对象,这样你可以创建同一个对象的多个实例。
HACK将创建一个几乎相同但名称不同的第二个对象字面值。
答
好了,我不知道如果我迟到后可能的解决方案,但在这里我去反正。
我不知道你的DOM结构或JS对象,但我会做这样的事情:
- 获取所有DOM元素或类型AddressEntry的JS对象,由某些类或特殊的属性。为了达到这个目的,你可能不得不改变其他地方。
- 循环每个元素并使用“Call”调用“init”函数。这样每个对象或元素都将绑定到您正在执行的初始化。
它看起来是这样的(未测试!!):
SFAIC.pages.salesProcess.Applicant = {
init : function() {
$('.addresses').each(function (i) {
SFAIC.ctrls.AddressEntry.init.call(this, this.attr('id'); });
}
};
的代码可能被窃听或缺乏几行代码,使其工作,但我认为这个想法是清楚的。希望它有帮助,你可以将它应用于你的案例。
纠正我,如果我错了:你试图初始化所有的AddressEntries(这是完全不同的对象或DOM元素)在一个函数(初始化函数的SFAIC.pages)。 – 2012-02-06 21:16:58
基本上。由于它是一个ASP.NET UserControl,UserControl的每个实例都使用不同的前缀ID呈现相同的元素。例如:AddressMailing控件中的AddressMailing_txtCity,AddressMailing_txtState等以及AddressGarage控件中的AddressGarage_txtCity,AddressGarage_txtState。 – 2012-02-06 21:47:17