1

私は次のように3つのクラスを作成しました

  1. Ext.mine.TextParent-テキストフィールドからの継承
  2. Ext.mine.child.TextChildA-Ext.mine.TextParentから継承
  3. Ext.mine.child.TextChildB-Ext.mine.TextParentから継承

このように、子Aクラスと子Bクラスはどちらも親クラスから継承しているため、兄弟です。

defalult値がであるtestConfigとして親クラスに新しいconfigプロパティを追加しました{}

of Child Aクラスで、initComponentこのtestConfigに新しいkey:valueを-として割り当てました。me.testConfig.childAKey='Child A Value';

これで、3つのテキストフィールドすべてを使用するフォームがあり、textChildBタイプのアフターレンダリングで、そのtestConfigの値を出力しています。

testConfigの値は子Bで変更されないため、空白のオブジェクトが出力されることが期待されます(このtestConfigの親のデフォルト値は空白のオブジェクトであるため)。

ただし、実際には子Aの値を出力します。

子Aと子Bは兄弟ですが、子Aの価値はどのようにして子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>
4

2 に答える 2

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); 
            }
        });
于 2012-07-06T08:21:34.193 に答える
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が値渡し型の文字列になっているため、正しく機能します。この背後にある理由は、JavaScriptのオブジェクトのディープコピーは非常に複雑で、多くのオブジェクトでは不可能であるため、Extjsはサブクラスのオブジェクトの新しいインスタンスを作成するように設計されていないためです。これは、一部の深いコピーが論理的に意味をなさない場合があるためです(循環参照を持つオブジェクトをコピーすることを考えてみてください。コピー関数は、いつ停止するかをどのように認識しますか?)。一部のディープコピーはオブジェクトに対して論理的に意味をなさないため、ディープコピーを実行するための一般化されたソリューションはありません。したがって、継承ツリーの最上位レベルでオブジェクトを作成すると、このオブジェクトは実際には同じインスタンスになります。すべてのサブクラスのそのオブジェクト。

extjsコアコードに気付いた場合、ほぼ100%の場合、すべての構成オプションは値型によって渡されます。これは、従うことになっているモデルです。あなたが提供した例では、それらすべての構成オプションをクラスレベルに置くことができれば、構成オプションのオブジェクトを作成する論理的な必要はなく、論理的に同じことを意味します。

私がここで言おうとしていることを本当に単純化したいのであれば、要約すると、参照渡しと値渡しのどちらになりますか。継承を正常に機能させる場合にのみ、構成オプションに値渡しを使用できます。

于 2012-07-06T14:40:26.570 に答える