0

我的整个 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。我可以做些什么来客观化SFAIC.ctrls.AddressEntry对象文字,以便能够处理我在页面上可能拥有的尽可能多的 AddressEntry UserControls 而不会相互覆盖?

4

3 回答 3

1

根据定义,对象字面量是对象的单个实例。也许您应该使用原型创建一个对象,这样您就可以创建同一个对象的多个实例。

HACK 是创建第二个几乎相同但名称不同的对象文字。

于 2012-02-06T21:09:36.397 回答
0

这是我想出的解决方案:

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");

    }

};
于 2012-02-06T21:43:33.310 回答
0

好吧,我不知道我是否迟到了发布可能的解决方案,但无论如何我都去了。

我不知道你的 DOM 结构或 JS 对象,但我会做这样的事情:

  1. 通过某个类或特殊属性获取所有类型为 AddressEntry 的 DOM 元素或 JS 对象。为了实现这一点,您可能必须在其他地方进行更改。
  2. 循环每个元素并使用“Call”调用“init”函数。这样每个对象或元素都将绑定到您正在执行的初始化。

它看起来像这样(未经测试!!):

SFAIC.pages.salesProcess.Applicant = {

    init : function() {         

        $('.addresses').each(function (i) {
            SFAIC.ctrls.AddressEntry.init.call(this, this.attr('id'); });
    }
};

代码可能存在错误或缺少更多行以使其工作,但我认为这个想法很清楚。希望它有所帮助,您可以将其应用于您的案例。

于 2012-02-06T22:14:51.790 回答