2012-07-06 185 views
1

我已經創建了3類如下問題與繼承

  1. Ext.mine.TextParent - 從文本字段Inherting
  2. Ext.mine.child.TextChildA - 從Ext.mine.TextParent
  3. Inherting
  4. 分機.mine.child.TextChildB - 從Ext.mine.TextParent吸入

這樣,Child A和Child B類是兄弟姐妹,因爲它們都是從Parent類中抽取的。

我添加了一個新的配置屬性父級作爲testConfig與defalult值爲{}

在兒童類的initComponent,我已經分配了一個新的密鑰:值這個testConfig爲 - me.testConfig.childAKey='Child A Value';

現在,有哪些是使用所有三個文本框,並在textChildB的一個AfterRender形式類型,我打印它的testConfig的值。

由於testConfig的值在Child B中未被修改,因此預期這應該打印空白對象(因爲此testConfig的父級中的默認值爲空白對象)。

但實際打印從兒童A.

兒童A和兒童B中的值是兄弟姐妹,因此,如何從兒童A的值來Child B級?

有人請指導一下,這可能是背後的原因?

下面是測試情況:

<html> 
    <head> 
     <title>Inheritance Test</title> 
     <link rel='stylesheet' href='resources/extjs/resources/css/ext-all.css' /> 
     <script type='text/javascript' src='resources/extjs/ext-all-dev.js'></script> 

     <script type='text/javascript'> 

      //Defining the Parent below 
      Ext.define('Ext.mine.TextParent', { 
       extend: 'Ext.form.field.Text', 
       alias: 'widget.textParent', 
       testConfig:{} 
      }); 

      //Defining the Child A below 
      Ext.define('Ext.mine.child.TextChildA', { 
       extend: 'Ext.mine.TextParent', 
       alias: 'widget.textChildA', 
       initComponent:function(){ 
        var me = this; 
        me.testConfig.childAKey  =  'Child A Value';//Adding the key value to Child A 
        me.callParent(); 
       } 
      }); 

      //Defining the Child B below 
      Ext.define('Ext.mine.child.TextChildB', { 
       extend: 'Ext.mine.TextParent', 
       alias: 'widget.textChildB' 
      }); 
     </script> 

     <script type='text/javascript'> 

      Ext.onReady(function(){ 
       Ext.create('Ext.form.Panel', { 
        title: 'Basic Form', 
        renderTo: Ext.getBody(), 
        width: 350, 
        url: 'save-form.php', 
        items: [{ 
         xtype: 'textParent',//Creating field for Parent 
         fieldLabel: 'Text Parent', 
         flex:1 
        },{ 
         xtype: 'textChildA',//Creating field for Child A 
         fieldLabel: 'Text Child A', 
         flex:1 
        },{ 
         xtype: 'textChildB',//Creating field for Child B 
         fieldLabel: 'Text Child B', 
         flex:1, 
         listeners:{ 
          afterrender:function(){ 
           /* 
            **Printing to console the value of testConfig for Child B 
            **Instead of giving a blank object, it is giving the values of Child A - childKey:Child A Value 
            **How the value from a sibling got associated with another one? 
           */ 
           console.log(this.testConfig); 
          } 
         } 
        }] 
       }); 
      }); 
     </script> 

    </head> 
    <body> 
    </body> 
</html> 

回答

2

這裏的問題是,你想繼承的對象(按引用傳遞),它的工作原理不是通過值類型,比如在ExtJS的數字和字符串傳遞完全不同。如果您將示例更改爲:

<script type='text/javascript'> 

      //Defining the Parent below 
      Ext.define('Ext.mine.TextParent', { 
       extend: 'Ext.form.field.Text', 
       alias: 'widget.textParent', 
       testConfig:"cheese" 
      }); 

      //Defining the Child A below 
      Ext.define('Ext.mine.child.TextChildA', { 
       extend: 'Ext.mine.TextParent', 
       alias: 'widget.textChildA', 
       constructor:function(){ 
        var me = this; 
        me.testConfig  =  'Child A Value';//Adding the key value to Child A 
        me.callParent(); 
       } 
      }); 

      //Defining the Child B below 
      Ext.define('Ext.mine.child.TextChildB', { 
       extend: 'Ext.mine.TextParent', 
       alias: 'widget.textChildB' 
      }); 
     </script> 

它會正常工作,因爲testConfig現在是傳值類型的字符串。之所以這樣做,是因爲Extjs沒有設計用於在子類中創建對象的新實例,因爲JavaScript中對象的深度副本非常複雜,甚至不可能用於許多對象。這是因爲一些深層副本甚至可能沒有邏輯意義(想想複製具有循環引用的對象,複製功能如何知道何時停止?)。由於某些深層副本對於對象不具有邏輯意義,因此可以不進行深層副本的一般化解決方案,因此如果您在繼承樹中以最高級別創建對象,則該對象實際上將是該對象爲每個子類。

如果您注意到extjs核心代碼幾乎100%的時間,所有配置選項都是按值類型傳遞的,並且這是您應該遵循的模型。在你提供的例子中,當你只需要將所有這些配置選項放在類級別時,創建配置選項對象就沒有必要了,它在邏輯上意味着同樣的事情。

我想如果你真的想簡化我在這裏說的話,它歸結爲傳遞與傳遞的價值。如果你希望繼承像它應該那樣工作,你只能使用配置選項的值傳遞。

+0

哦,如果你真的想保持配置選項作爲一個對象,user993553是真正做到這一點的唯一方法,而不會像你在例子中看到的副作用。 – Reimius 2012-07-06 14:41:53

+0

感謝您的詳細解答。我只是想知道這是否違反了OOP中的一般原則,其中兩個兄弟姐妹將被完全相互獨立? – netemp 2012-07-09 10:04:47

+0

理想情況下,您的原始示例可以在OOP模型中工作,但JavaScript的本質限制使得它不完全適合此模型,但Extjs已盡其最大努力做到這一點。 – Reimius 2012-07-09 14:01:43

2

未做textChildA自己的「實例」 testConfig的,this.testConfig正在改變父母的價值,嘗試添加在textParent的xtype場相同的偵聽器,和你將認爲該值包含childAKey和value。

Ext.define('Ext.mine.child.TextChildA', { 
      extend: 'Ext.mine.TextParent', 
      alias: 'widget.textChildA', 
      initComponent:function(){ 
      Ext.apply(this,{ 
     testConfig:{'childAKey':"valuea"} 
     }); 
     this.callParent(arguments); 
      } 
     }); 
+0

感謝帖子user993553。您共享的方法當然是一種不會導致這種衝突的替代方式,這也是我們實際上一直在使用的方式。但我們在這裏所關心的問題是,一個兄弟姐妹的財產如何來到另一個兄弟的財產?你可以談談這個問題嗎? – netemp 2012-07-06 08:48:58

+0

感謝您修改答案並添加詳細信息。正如你所提到的那樣 - '沒有讓textChildA自己的testConfig的「實例」,this.testConfig正在改變父母的值。如果是這種情況,那麼它怎麼會被添加到「班級定義」並影響孩子B? – netemp 2012-07-06 09:34:58