Установить прослушиватель для хранения событий в контроллере
У меня есть контроллер с магазином, моделью и некоторыми представлениями.
Мне нужно прослушать события 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
}
});
},
...
Мой ожидаемый результат состоит в том, что функции будут выполняться при запуске событий.
Но в это время ничего не происходит, когда они увольняются.
Как я могу заставить это работать?
Ответы
Ответ 1
Ваш способ возможен, но он не идеален, ИМО. Лучше всего использовать контроллеры для хранения геттера. В вашем случае код будет примерно таким:
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
});
},
Ответ 2
Вот альтернативный синтаксис для ответа Molecular Man.
Вместо записи
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
});
},
Я думаю, что это альтернативное определение читается немного лучше.
Я взял это из ответа Izhaki.
Ответ 3
Как и для 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
Ext.define('Store', {
model: 'Model',
extend: 'Ext.data.Store',
listeners: {
'beforesync': function(){
App.getController('somecontroller').onBeforeSync();
}
}
});
App - ваш объект приложения
Функция onBeforeSync вы можете реализовать ее в контроллере... это единственный способ, которым я мог назначить событие в хранилище и все еще реализовать логику в controll. Я надеюсь, что это поможет
Ответ 5
Я решил это сам.
Я добавил слушателя вручную в render
-event моей панели
Ext.getCmp('userPanel').down('gridpanel').getStore().addListener('write',this.finishedLoading, this);
Спасибо за помощь @nscrob.
Ответ 6
Надеемся, что это дополнение поможет кому-то, чтобы не тратить несколько часов на отладку ядра библиотеки:
В связи с этой практикой доступа к экземпляру Ext.data.Store внутри контроллера с использованием метода getter-контроллера: например, для "DT.store.UsersStore" выше, используя this.getUsersStoreStore():
обратите внимание, что если хранилище уже связано в представлении (например, было объявлено как свойство хранилища для определения виджетов Grid.panel.Panel "UserGrid" ), то этот метод getter будет фактически получать другой экземпляр тот же класс Store, а не экземпляр, используемый виджетами!Причина в том, что добавление хранилища в объект конфигурации конструктора выглядит следующим образом:
stores: ['UsersStore']
фактически добавит новый экземпляр магазина в хэш файл Ext.data.StoreManager.map, так что предположим, что "UsersStore" - это единственный объект Store, созданный до сих пор - теперь клавиши карты выглядят следующим образом:
0: "ext-empty-store"
1: "UsersStore"
2: "myStore"
Теперь представьте, что вы хотите прочитать некоторые новые данные, используя свой store'proxy, и отобразить эти новые данные в "UserGrid", и вы хотите сделать все это, когда пользователь нажимает на что-то, поэтому внутри контроллера вы будете иметь метод обработчика для пользовательское событие с кодом:
'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')
Ответ 7
Почему бы просто не передать события магазина? Например:
this.getUsersGrid().relayEvents(this.getUsersStoreStore(), ['write'], 'store')
А затем уметь
this.control('somegrid-selector': {storeWrite: function(){...}})