7

ユーザーが選択できるアイテムを含むグリッドと、グリッドのコンテンツをフィルター処理するために使用できる小さなテキスト フィールドを持つ、再利用可能なアイテム選択パネルを作成しようとしています。現在、(簡略化された) ビュー コードは次のようになり、動作します。

Ext.define('MyApp.view.items.ItemSelectorPanel', {
    extend: 'Ext.panel.Panel',
    require: 'MyApp.view.items.SimpleItemGrid',
    alias: 'widget.ItemSelectorPanel',
    layout: 'form',

    config: {
        itemStore: false
    },

    constructor: function(config) {
        this.initConfig(config);

        this.superclass.constructor.call(this, config);

        this.add([
            {
                fieldLabel: 'Filter',
                name: 'filter'
            },
            {
                xtype: 'SimpleItemGrid',
                collapsible: true,
                store: this.getItemStore()
            }
        ]);

        return this;
    }
});

ご覧のとおり、はプロパティをItemSelectorPanel使用してconfig、呼び出し元のサイトが使用するアイテム ストアを指定できるインターフェイスを公開します。

呼び出しサイト (この場合、パネルは TabPanel に追加されます):

var panelToAdd = {
    xtype: 'panel',
    title: 'New Selection',
    closable: true,
    padding: 10,
    items: [{
        title: 'Select node',
        xtype: 'ItemSelectorPanel',
        itemStore: itemStore
    }]
};

今では、ExtJS 4 の宣言型スタイルと、それが MVC パターンに従うのにどのように役立つかが気に入っています。ビューで可能な限り最小限のコードを使用することをお勧めします。残念ながら、これは機能しません:

Ext.define('MyApp.view.items.ItemSelectorPanel', {
    /* ... same as above ... */

    constructor: function(config) {
        this.initConfig(config);

        this.superclass.constructor.call(this, config);

        return this;
    },

    items: [
            {
                fieldLabel: 'Filter',
                name: 'filter'
            },
            {
                xtype: 'SimpleItemGrid',
                collapsible: true,
                store: this.getItemStore   // <-- interesting part
            }
    ]
});

config親プロパティのプロパティを介してネストされた/サブコンポーネントの構成を宣言的に公開する方法はありますか?

4

4 に答える 4

6

まず一般的なこと

何をしようとしているのか正確にわかっていない限り、クラス定義内の関数の外にオブジェクトを追加しないでくださいそうする場合、すべてのインスタンスがそのオブジェクトの同じインスタンスを共有します。これがどこにつながるかについて言及する必要はないと思います...

そこにオブジェクトを配置する必要がある場合は、コンストラクター内で複製する必要があります。

あなたのコードに

私は何をするのかわかりthis.initConfig(config);ませんが、config変数はあなたのクラスのものではなく、コンストラクター引数のものです。コンストラクターを使用する必要性が定義されていない限りinitComponent()、の代わりに初期化にも使用することをお勧めします。constructor()

また、「構成」は転送されません。これは、構成が上に移動し、他のすべてのプロパティが (既に) 継承されている場合に、上から下に実行されるのではなく、下から上に実行されるためです。

私はまだあなたの目標が何であるかを正確に知りません.

編集

あなたのニーズを完全に理解しているかどうかはまだわかりませんが、次のように動作するはずです (リスナーも必要な場合は、ミックスインを確認してくださいExt.util.Bindable) 。

Ext.define('MyApp.view.items.ItemSelectorPanel', {
    extend: 'Ext.panel.Panel',
    require: 'MyApp.view.items.SimpleItemGrid',
    alias: 'widget.ItemSelectorPanel',
    layout: 'form',

    initComponent: function() {
        // Initialize the store (might be a instance or a storeId)
        var store;
        if (this.itemStore) {
            store = Ext.data.StoreManager.lookup(store);
        }
        this.itemStore = store || null;
        // Add is not valid (at least not before the parent inits are executed)
        this.items = [{
            fieldLabel: 'Filter',
            name: 'filter'
        }, {
            xtype: 'SimpleItemGrid',
            collapsible: true,
            store: this.getItemStore()
        }];

        this.callParent(arguments);
    },

    getItemStore: function() {
        return this.itemStore;
    }
});
于 2013-01-18T10:49:41.610 に答える
2

いいえ、あなたが説明した方法でそれを行うことはできません。理由は非常に単純です。これを例として取り上げましょう。

Ext.define('MyClass', {
    someProp: this.foo(),

    foo: function(){
        return bar;
    }
});

ここでは、define()メソッドを呼び出し、それを構成としてオブジェクトとして渡します。そのため、オブジェクト全体(foo()の呼び出しを含む)は、defineに渡される前に評価されるため、その時点ではクラス/メソッドも存在しません。

それができたとしても、fooがクラスのインスタンスメソッドであるという複雑さもありますが、それを呼び出そうとしている方法は、静的メソッドであるかのようです。

したがって、答えは、そうするために何らかのメソッドを使用する必要があるということです。通常、initComponentはコンストラクターよりも優先されます。

于 2013-01-18T10:59:45.443 に答える
1

クラスの宣言でアイテムを定義できますが、宣言時にクラスからメソッドを呼び出すことはできません。これを解決するには、ストアのないアイテムのみを定義し、initComponent メソッドを使用してビューのストアを設定します。

于 2013-01-18T11:09:56.530 に答える