Установить прослушиватель для событий магазина в контроллере - PullRequest
28 голосов
/ 25 августа 2011

У меня есть контроллер с магазином, моделью и некоторыми представлениями.

Мне нужно прослушать событие beforesync и write магазина в контроллере, но я незнать, как настроить этих слушателей в функции контроллера control.

Мой магазин выглядит так:

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
        }
    });
},
...

Мой ожидаемый результат заключается в том, что функции будут выполнены, когда будут запущены события.Но в это время ничего не происходит, когда их увольняют.

Как я могу заставить это работать?

Ответы [ 7 ]

33 голосов
/ 28 августа 2011

Ваш путь возможен, но не идеален, ИМО.Лучше всего использовать метод получения хранилища контроллеров.В вашем случае код будет выглядеть примерно так:

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
    });
},
19 голосов
/ 09 августа 2012

Вот альтернативный синтаксис Ответ Молекулярного Человека .

Вместо записи

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
    });
},

Я думаю, что это альтернативное определение читается немного лучше.

Я взял это из ответа Изаки дал мне.

5 голосов
/ 04 сентября 2013

Что касается Extjs 4.2.1, ваш первоначальный способ доступа к слушателю хранилища будет действительно работать, если вы используете 'storeId' вместо id и функцию 'listen' вместо 'control':

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

init : function () {
    this.listen({
        store: {
           '#myStore' : {
               beforesync : this.doSomething,
               ...
4 голосов
/ 26 августа 2011

Я решил это сам.

Я добавил слушателя вручную в render событие моей панели

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

Спасибо за помощь @ nscrob.

4 голосов
/ 25 августа 2011
Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});

Приложение - ваш объект приложения Функция onBeforeSync, которую вы можете реализовать в контроллере ... это единственный способ, которым я мог бы назначить событие хранилищу и при этом реализовать логику в контроллере.Надеюсь, это поможет

1 голос
/ 21 февраля 2014

Надеюсь, что это дополнение поможет кому-то избежать затрат времени на отладку ядра библиотеки:

С этим связано обращение к экземпляру Ext.data.Store внутри Controller с использованием метода get контроллера: например, для«DT.store.UsersStore» выше с использованием this.getUsersStoreStore ():

обратите внимание, что если хранилище уже связано в представлении (например, было объявлено как свойство хранилища для Grid.panel «UsersGrid»).Определение виджета .Panel), тогда этот метод getter фактически получит другой экземпляр того же класса Store, а не экземпляр, используемый виджетом! Причина заключается в том, что добавление хранилища в объект конфигурации конструктора выполняется следующим образом:

stores: ['UsersStore']

фактически добавит новый экземпляр хранилища в хеш Ext.data.StoreManager.map, так что - предположим, что «UsersStore» - единственный экземпляр хранилища, созданный на данный момент - ключи карты теперь выглядят так:

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

Теперь представьте, что вы хотите прочитать некоторые новые данные, используя прокси вашего магазина и дидобавьте эти новые данные в «UsersGrid», и вы захотите сделать все это, когда пользователь нажимает на что-то, поэтому внутри контроллера у вас будет метод обработчика для пользовательского события с кодом:

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

Этот вызовчтобы получить ссылку, она будет внутренне переведена в this.getStore («UsersStore») и вернет ссылку на сгенерированный контроллер - 1: «UsersStore», а не - 2: «myStore» - как и следовало ожидать.Кроме того, вызов load () загрузит экземпляр UsersStore с новыми моделями, и это не будет отражено в вашем представлении сетки (поскольку сетка привязана и прослушивает события, сгенерированные экземпляром хранилища "myStore").

Так что лучше получите доступ к хранилищу по его itemId, используя общий метод getStore: this.getStore ('storeItemId')

0 голосов
/ 14 февраля 2014

Почему бы просто не передать события магазина?Например:

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

А затем сможете

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

...