Установить прослушиватель для хранения событий в контроллере

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

Мне нужно прослушивать события 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
        }
    });
},
...

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

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


person Demnogonis    schedule 25.08.2011    source источник


Ответы (8)


Ваш способ возможен, но это не идеал, имхо. Лучший способ - использовать геттер хранилища контроллеров. В вашем случае код будет примерно таким:

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
    });
},
person Molecular Man    schedule 28.08.2011
comment
Даже лучше, чем мое решение. Спасибо чувак. Это потрясающее сообщество. - person Demnogonis; 30.08.2011
comment
Будет ли это решение работать правильно, ТОЛЬКО выполняя код в той части приложения, которая использует контроллер, в котором вы это определяете? Или событие затронет этого нового слушателя с этого момента? - person CDelaney; 24.01.2012
comment
Я думаю, что это будет работать только внутри этого контроллера, но я точно не знаю, потому что я никогда не использовал несколько контроллеров в одном приложении. - person Demnogonis; 19.03.2012
comment
Похоже, что в бета-версии ST2.1 нет никаких геттеров для магазинов. - person wprater; 31.08.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
    });
},

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

Я взял это из ответа Ицхаки, который дал мне.

person James McMahon    schedule 08.08.2012
comment
Можем ли мы добавить более 1 слушателя, используя on()? - person aswininayak; 05.04.2013
comment
из всех решений на этой странице у меня сработало только this.getUsersStoreStore().on({... (Используя 4.2.1) - person Geo; 18.06.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,
               ...
person Automatix    schedule 04.09.2013

Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});

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

person nscrob    schedule 25.08.2011
comment
Нет, это не работает. this.doSomething должен выполнить console.log('BeforeSync'); но все равно ничего не происходит - person Demnogonis; 25.08.2011
comment
хорошо, проблема явно в том, что слушатель не назначен компоненту. Вы должны прочитать документацию для запроса в extjs, который используется для определения того, для какого компонента вы назначаете событие. Попробуйте что-то вроде «имя виджета gridPanel #store» (где имя виджета — это представление, назначенное контроллеру). В данный момент мне нечего тестировать, но вы должны сделать это шаг за шагом, сначала добавить событие в компонент, содержащий это хранилище, а затем попытаться установить события в хранилище. - person nscrob; 25.08.2011
comment
D'oh ... Я обнаружил, что класс хранилища не имеет ни идентификатора, ни конфигурации псевдонима. Мои конфиги будут проигнорированы и пункт не будет назначен в контроллере. Есть ли другой способ? - person Demnogonis; 26.08.2011
comment
Искал альтернативы и не нашел. Функция управления использует компонентный запрос для получения компонентов и хранения, это не компонент ext, он расширяет ext.base, поэтому я считаю, что невозможно получить хранилище с помощью запроса компонента. Я как-то нашел альтернативу, я изменю ответ выше найденным решением - person nscrob; 26.08.2011
comment
Пожалуйста, не связывайте свой магазин с контроллером, это очень плохая идея, вы не можете повторно использовать этот магазин в другой части вашего приложения. - person Martin Lantzsch; 26.06.2014

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

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

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

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

person Demnogonis    schedule 26.08.2011

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

Связано с этой практикой доступа к экземпляру Ext.data.Store внутри контроллера с использованием метода получения контроллера: например. для "DT.store.UsersStore" выше, используя this.getUsersStoreStore():

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

stores: ['UsersStore']

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

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')

person Galileo_Galilei    schedule 21.02.2014

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

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

А потом суметь

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

person Andrei Neculau    schedule 14.02.2014

На всякий случай, если кто-то споткнется об это.

ExtJS 7.3

Ext.define('DT.controller.UsersStore', {
    extend: 'Ext.app.Controller',

    listen: {
        store: {
            UsersStore: {
                beforesync : 'doSomething',
                write : 'doSomethingElse'
            }
        }
    },

    doSomething() {
        console.log(arguments)
    },

    doSomethingElse() {
        console.log(arguments)
    }
});
person Robert R.    schedule 09.04.2021