19.06.2015, 20:40
|
Аспирант
|
|
Регистрация: 01.06.2015
Сообщений: 57
|
|
initComponent: Как получить данные родителя и как получить store для вызова load()?
Всем привет.
Есть форма, внутри которой моя таблица. Нужно при открытии формы загрузить данные в таблицу с сервера. Единственное до чего додумался это использовать initComponent в моей таблице. Таблица как бы независимая и имеет свой контролер.
Но не знаю как получить Id родителя (формы), при том не тот что генерируется ExtJS, а с сервера, т.е. ИД из данных в форме. Пробую, получить, вызывая
this.findParentByType('orderEdit').getViewModel().data.singleOrder
но получаю значение по умолчанию, оно у меня null, получается родительская форма не получила ещё свои данные на момент создания таблицы. Как правильно это сделать, может как-то по другому данные родителя получать?
Помимо этого надо чтобы таблица загрузила с сервера данные, вроде надо вызвать store.load() таблицы, но стор таблицы тоже получить не могу, пишет что он пустой, типа вообще не определен. Как бы выходит что и стор тоже ещё не подсоединился к моей таблицы. (У формы свой стор, у таблицы свой.)
Как всё это дело получить? Может быть это надо делать в другом месте, а не в initComponent?
|
|
20.06.2015, 17:04
|
Профессор
|
|
Регистрация: 07.08.2013
Сообщений: 214
|
|
в javascript в целом и в extjs в частности сломать всё можно миллионом способов. нужен тест кейс
|
|
20.06.2015, 18:30
|
Аспирант
|
|
Регистрация: 01.06.2015
Сообщений: 57
|
|
Тут по моему не то что сломано, а просто наверное что-то не правильно делаю или вообще такое не предусмотрено.
Попробую сформулировать один из вопросов по другому. Если я в store устанавливаю autoLoad: false то как при показе таблицы мне загрузить в неё данные? Т.е. автозагрузка отключена и значит таблица будет пустая. В какой момент и где мне вызвать функцию store.load()?
|
|
20.06.2015, 20:36
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
может быть вызвать store.load() в обработчике события afterrender вашей таблицы. Обработчик можно определить в том числе и внутри initComponent:
this.listeners = {
afterrender: function(grid) { grid.getStore().load(); }
}
Гадать, не хочется. Выложите кусок кода хотя бы...
|
|
20.06.2015, 20:37
|
Аспирант
|
|
Регистрация: 01.06.2015
Сообщений: 57
|
|
Кажется нашел как решить проблему загрузки таблицы без автозагрузки. Но очень удивлен тем как это сделано. Я почему-то думал, если определил модель, стор и view, то всё автоматом создастся и свяжется между собой. а как видно из куска кода ниже, ничего подобного. Без автозагрузки в сторе, стор надо создавать самому и явно, а не пытаться к нему обратиться. Как-то не очевидно для меня.
Ext.define('JournalApp.view.notes.Note', {
extend: 'Ext.grid.Panel', //'Ext.panel.Panel',//
noteStore: null,
initComponent: function() {
this.callParent();
this.noteStore = Ext.getStore('JournalApp.store.NoteStore');
this.on('render', this.loadStore, this);
},
loadStore: function() {
this.noteStore.load({
scope: this,
params: {
orderid: 'тут ид родителя таблицы, но как получить?'
}
});
},
Если это так, то данные из родительского контейнера не получить, если не создать их самому явно, но они существуют. Ума не приложу как теперь получить данные из контейнера, содержащего мою таблицу.
|
|
20.06.2015, 20:55
|
Аспирант
|
|
Регистрация: 01.06.2015
Сообщений: 57
|
|
Я пробовал через это событие (похоже я его угадал, если вы предложили ), но там тоже при вызове load() пишет ошибку. Но кажется данный кусок проблемы решился, но как-то неожиданным образом, как в вашем примере для меня было бы логичней.
Теперь надо получить данные из контейнера, содержащего эту таблицу. Пробую это делать в той же функции initComponent, но там все данные пустые, а мне всего лишь нужен Id, но не служебный, а тот что с сервера был получен.
Я выше выложил кусок кода и по сути у меня это всё что относиться к данной проблеме. Если нужно я конечно могу выложить весь код, но там большие портянки и даже не знаю, что именно из этого поможет решить проблему.
Может быть к тому что в посте выше ещё можно показать какая у меня иерархия компонентов. Вот так я определил форму и в ней мою таблицу, initComponent из которой я привел выше. (Убрал что явно я думаю не по делу, типа заголовка формы, другие поля и т.п.)
Ext.define('JournalApp.view.orders.OrderEdit', {
extend: 'Ext.form.Panel',
xtype: 'orderEdit',
requires: [
'JournalApp.view.orders.OrderViewModel',
'JournalApp.view.notes.Note',
],
controller: 'orders',
viewModel: {
type: 'order'
},
items: [{
xtype: 'noteGrid',
fieldLabel: 'Заметки:',
viewModel: {
type: 'order'
},
bind: {
store: '{notes}'
},
}]
});
Сообщение от novikov
|
может быть вызвать store.load() в обработчике события afterrender вашей таблицы. Обработчик можно определить в том числе и внутри initComponent:
this.listeners = {
afterrender: function(grid) { grid.getStore().load(); }
}
Гадать, не хочется. Выложите кусок кода хотя бы...
|
|
|
20.06.2015, 21:03
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
Ext.define('JournalApp.view.notes.Note', {
extend: 'Ext.grid.Panel', //'Ext.panel.Panel',//
alias: 'widget.myGrid', // <-- подобным образом напишите в родительской форме widget.myForm
noteStore: null,
initComponent: function() {
this.callParent();
this.noteStore = Ext.getStore('JournalApp.store.NoteStore');
this.on('render', this.loadStore, this);
},
loadStore: function(grid) {
var formId = grid.up('myForm').getViewModel().data.singleOrder; // <-- ищем форму по alias myForm
this.noteStore.load({
scope: this,
params: {
orderid: formId
}
});
},
|
|
20.06.2015, 21:07
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
хранилище грида можно назначать и во ViewModel, если мне не изменяет память. Там есть спецпараметр stores.
|
|
20.06.2015, 21:47
|
Аспирант
|
|
Регистрация: 01.06.2015
Сообщений: 57
|
|
К сожалению это не помогло. Возвращает значение, которое у меня указано по умолчанию. Оно при открытии формы заменяется на текущее. Получается данные ещё не загрузились в форму, ну как я думаю.
Вот так выглядит моя ViewModel:
Ext.define('JournalApp.view.orders.OrderViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.order',
requires: [
'JournalApp.model.OrderModel',
'JournalApp.store.NoteStore'
],
data: {
name: 'Разделы',
singleOrder: null // <--- ВОЗВРАЩАЕТ ВОТ ЭТОТ NULL ВМЕСТО ДАННЫХ
},
stores: {
orders: {
model: 'OrderModel',
autoLoad: true,
autoSync: true,
sorters: [{
property: 'createddate',
direction: 'DESC'
}],
proxy: {
type: 'rest',
url : 'journal/orders/',
//pageParam: '',
//startParam: '',
//limitParam: '',
reader: {
type: 'json',
rootProperty: 'orders'
},
writer: {
type: 'json',
writeAllFields: true, // это чтобы все поля передавать на сервер.
allDataOptions: {
associated: true // <- THE MOST IMPORTANT CHANGE (С этим стал передвать вложенные модели)
},
}
}
},
strategys: {
source: 'JournalApp.store.StrategyStore',
},
notes: {
source: 'JournalApp.store.NoteStore',
}
}
});
Форма у меня создается в закладке Tab и ей присваиваются данные, которые я передаю из строки главной таблицы, не той о которой сейчас идет разговор, а другая. Вот такой строкой я присваиваю данные:
orderTab.getViewModel().setData({ singleOrder: record });
И они присваиваются, их даже видно в переменной formId из вашего примера, если вызвать console.log(formId), но только в момент выполнения там null, а не данные.
Я пытался делать через grid.findParentByType('orderEdit').getViewModel(). data.singleOrder , но там то же самое, в момент вызова null, а в консоли потом есть все данные.
Вот так вызвал логи и прикрепил картинку, того как это выглядит в итоге:
var formId = grid.up('orderEdit').getViewModel().data.singleOrder;
console.log('formId', formId);
console.log('data', grid.up('orderEdit').getViewModel().data);
Сообщение от novikov
|
Ext.define('JournalApp.view.notes.Note', {
extend: 'Ext.grid.Panel', //'Ext.panel.Panel',//
alias: 'widget.myGrid', // <-- подобным образом напишите в родительской форме widget.myForm
noteStore: null,
initComponent: function() {
this.callParent();
this.noteStore = Ext.getStore('JournalApp.store.NoteStore');
this.on('render', this.loadStore, this);
},
loadStore: function(grid) {
var formId = grid.up('myForm').getViewModel().data.singleOrder; // <-- ищем форму по alias myForm
this.noteStore.load({
scope: this,
params: {
orderid: formId
}
});
},
|
|
|
21.06.2015, 09:16
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
Правильно ли я понимаю, что при клике по узлу "Ордера" в левом дереве в правой части появляется панель с одной закладкой, которая содержит таблицу со всеми ордерами, и под ней таблица со всеми заметками. Потом при клике на отдельный ордер в общем списке проявляется сбоку от него форма с данными ордера, а нижняя панель заметок фильтруется под выбранный ордер.
Если так, то после клика по строке ордера при создании нового экземпляра формы можно назначить ссылку на выбранную запись во ViewModel через links или linkTo.
У таблицы заметок есть своё хранилище. На мой взгляд, лучше найти этот компонет при помощи up() и down(), затем извлечь его хранилище через getStore() и выполнить фильтрацию filter(), указав в фильтре id выбранного ордера. Благо в обработчике события selectionchange, выполняющем всю эту логику есть информация о выбранной строке.
Поправьте, если я чего недопонял в задаче.
|
|
|
|