web-dev-qa-db-ja.com

コントローラーにストアイベントのリスナーを設定する

ストア、モデル、およびいくつかのビューを持つコントローラーがあります。

コントローラーのストアのbeforesyncおよびwriteイベントをリッスンする必要がありますが、コントローラーでこれらのリスナーを設定する方法がわかりませんcontrol- function。

私の店は次のようになります:

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    id : 'myStore'
    autoSync : true,
    proxy : {
        type : 'ajax',
        api : {
            read : '/load_entries',
            update : '/update_entry'
        },
        reader : {
            type : 'json',
            root : 'user',
            successProperty : 'success'
        }
    }
});

次に、コントローラーでイベントをリッスンしてみます。

...
init : function () {
    this.control({
        'myStore' : {
            beforesync : this.doSomething,
            write : this.doSomethingElse
        }
    });
},
...

私の期待される結果は、イベントが発生したときに関数が実行されることです。しかし、現時点では、彼らが解雇されても何も起こりません。

これを機能させるにはどうすればよいですか?

28
Demnogonis

Your way は可能ですが、理想的ではありません、IMO。より良い方法は、コントローラーのストアゲッターを使用することです。あなたの場合、コードは次のようになります:

init : function () {
    // every controller has getters for its stores.
    // For store UsersStore getter would be getUsersStoreStore()
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},
33
Molecular Man

Molecular Man's answer の代替構文を次に示します。

書く代わりに

init : function () {
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},

あなたは書ける

init : function () {
    this.getUsersStoreStore().on({
        write: this.finishedLoading,
        scope: this
    });
    this.control({
        // widgets event handlers
    });
},

この別の定義の方が少し読みやすいと思います。

これを answer Izhaki から受け取った。

19
James McMahon

Extjs 4.2.1に関しては、IDの代わりに 'storeId'を使用し、 'control'の代わりに 'listen'関数を使用した場合、ストアリスナーにアクセスする最初の方法は実際に機能します。

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    storeId : 'myStore'
    ....

init : function () {
    this.listen({
        store: {
           '#myStore' : {
               beforesync : this.doSomething,
               ...
5
gambetti
Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});

アプリ-アプリケーションオブジェクトコントローラーに実装できる関数onBeforeSync ...これは、イベントをストアに割り当て、ロジックをコントロールに実装できる唯一の方法です。それが役に立てば幸い

4
nscrob

自分で解決しました。

パネルのrender- eventにリスナーを手動で追加しました

Ext.getCmp('userPanel').down('gridpanel').getStore().addListener('write',this.finishedLoading, this);

ヘルプ@nscrobをありがとう。

4
Demnogonis

この追加が、ライブラリコアのデバッグに数時間を費やすことを回避するのに役立つことを願っています。

コントローラーのゲッターメソッドを使用して、コントローラー内でExt.data.Storeインスタンスにアクセスするこのプラクティスに関連します。 this.getUsersStoreStore()を使用した上記の「DT.store.UsersStore」の場合:

ストアが既にビューに関連付けられている場合(たとえば、「UsersGrid」Grid.panel.Panelウィジェット定義のストアプロパティとして宣言されている場合)、このgetterメソッドは実際に同じの別のインスタンスを取得します)ウィジェットで使用されるインスタンスではなく、ストアクラス!理由は、次のようにコンストラクター構成オブジェクトにストアを追加するためです。

stores: ['UsersStore']

実際には、Ext.data.StoreManager.mapハッシュに新しいストアインスタンスを追加するため、これまでにインスタンス化された唯一のStoreオブジェクトが 'UsersStore'であるとすると、マップキーは次のようになります。

0: "ext-empty-store"
1: "UsersStore"
2: "myStore"

ここで、store'proxyを使用していくつかの新しいデータを読み取り、「UsersGrid」にこの新しいデータを表示し、ユーザーが何かをクリックしたときにこれらすべてを実行したいので、コントローラー内にユーザーイベントのハンドラーメソッドがあるとします。コードで:

'user-selector' : {
    click: function(){
                     var oStoreReference = this.getUsersStoreStore();
                         oStoreReference.load( {params:{} });
            }
    }

参照を取得するための呼び出しは、this.getStore( 'UsersStore')で内部的に変換され、生成されたコントローラーへの参照を返します。さらに、load()呼び出しは新しいモデルでUsersStoreインスタンスをロードし、これはグリッドビューには反映されません(グリッドがバインドされ、「myStore」ストアインスタンスによって生成されたイベントをリッスンするため)。

したがって、一般的なgetStoreメソッドを使用して、itemIdでストアにアクセスしやすくします:this.getStore( 'storeItemId')

1
Galileo_Galilei

店舗のイベントを中継しないのはなぜですか?例えば:

this.getUsersGrid().relayEvents(this.getUsersStoreStore(), ['write'], 'store')

そしてそれから

this.control('somegrid-selector': {storeWrite: function(){...}})

0
Andrei Neculau