2012-02-06 81 views
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。我能做些什么来将对象化为:我可以在页面上处理尽可能多的AddressEntry UserControls,而不会互相覆盖对象,从而使对象字面量化?

+0

纠正我,如果我错了:你试图初始化所有的AddressEntries(这是完全不同的对象或DOM元素)在一个函数(初始化函数的SFAIC.pages)。 – 2012-02-06 21:16:58

+0

基本上。由于它是一个ASP.NET UserControl,UserControl的每个实例都使用不同的前缀ID呈现相同的元素。例如:AddressMailing控件中的AddressMailing_txtCity,AddressMailing_txtState等以及AddressGarage控件中的AddressGarage_txtCity,AddressGarage_txtState。 – 2012-02-06 21:47:17

回答

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

    } 

}; 
1

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

HACK将创建一个几乎相同但名称不同的第二个对象字面值。

0

好了,我不知道如果我迟到后可能的解决方案,但在这里我去反正。

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

  1. 获取所有DOM元素或类型AddressEntry的JS对象,由某些类或特殊的属性。为了达到这个目的,你可能不得不改变其他地方。
  2. 循环每个元素并使用“Call”调用“init”函数。这样每个对象或元素都将绑定到您正在执行的初始化。

它看起来是这样的(未测试!!):

SFAIC.pages.salesProcess.Applicant = { 

    init : function() {   

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

的代码可能被窃听或缺乏几行代码,使其工作,但我认为这个想法是清楚的。希望它有帮助,你可以将它应用于你的案例。