Extコンポーネントの継承

↓のチュートリアルについてのメモです。
Manual:Component:Extending Ext Components / Ext.js

Extのコンポーネントを使う場合には、以下のGridPanelの例の様にコンストラクタの引数として、コンポーネントの設定を行うためのコンフィグオプションをハッシュで渡します。

var grid = new Ext.grid.GridPanel({
    // GridPanelのコンフィグオプション
    store: new Ext.data.Store({
      // Storeのコンフィグオプション
        reader: reader,
        data: xg.dummyData
    }),
    columns: [
        {id:'company', header: "Company", width: 200, sortable: true, dataIndex: 'company'},
        {header: "Price", width: 120, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
        {header: "Change", width: 120, sortable: true, dataIndex: 'change'},
        {header: "% Change", width: 120, sortable: true, dataIndex: 'pctChange'},
        {header: "Last Updated", width: 135, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
    ],
    // ....省略
});

コンポーネントを生成するたびにコンフィグオプションを指定するのは煩わしいので、Extのコンポーネントを継承したClassを定義します。これは"Pre-configured Class"と呼ばれます。

// Ext.some.componentのPre-configured ClassであるMyComponentを定義する
MyComponent = Ext.extend(Ext.some.component, {
    myDefault1: '..',
    myDefault2: '..'
});
 
// lazy initializationのためのxtypeを登録する
Ext.reg('mycomponentxtype', MyComponent);

// あとは普通に使う
var myComponent = new MyComponent();

xtypeを登録しておくと、↑のようにコンポーネントを明示的に生成しなくてもPanelやLayoutのitemsプロパティで指定することで自動的に生成することができます。

{..
   items: [ {xtype: 'mycomponentxtype'} ]
..}

元のクラスのプロパティやメソッドをオーバーライドするには、

MyComponent = Ext.extend(Ext.some.component, {
    // プロトタイプのデフォルト値。ユーザが指定したコンフィグオプションで上書きできる。
    propA: 1,
 
    initComponent: function(){
        // コンポーネントの初期化中に呼ばれる。

        // コンフィグオブジェクトはすでにthisに適用済みなので、ここで、上書きしたり
        // 新しく追加することが可能
        Ext.apply(this, {
            propA: 3
        });
 
        // 親クラスのコードの実行前
 
        // 親クラスのコードの実行(必須)
        MyComponent.superclass.initComponent.apply(this, arguments);
 
        // 親クラスのコードの実行後(イベントハンドラの追加やコンポーネントの描画など)
    },
 
    // 継承したメソッドのオーバーライド 
    onRender: function(){
 
        // 親クラスのコードの実行前
 
        // 親クラスのコードの実行(必須)
        MyScope.superclass.onRender.apply(this, arguments);
 
        // 親クラスのコードの実行後
 
    }
});
 
// lazy initializationのためのxtypeを登録する
Ext.reg('mycomponentxtype', MyComponent);

のようにします。

var myComponent = new MyComponent({
    propA: 2
});
// Or lazily:
{..
  items: {xtype: 'mycomponentxtype', propA: 2}
..}

これを実行すると、propAの値は、1(プロトタイプのデフォルト値)→2(コンストラクタで指定したコンフィグの値)→3(initComponentで上書した値)の順に3回変更されます。