Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   initComponent: Как получить данные родителя и как получить store для вызова load()? (https://javascript.ru/forum/extjs/56516-initcomponent-kak-poluchit-dannye-roditelya-i-kak-poluchit-store-dlya-vyzova-load.html)

Пролетарий 19.06.2015 20:40

initComponent: Как получить данные родителя и как получить store для вызова load()?
 
Всем привет.

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

Но не знаю как получить Id родителя (формы), при том не тот что генерируется ExtJS, а с сервера, т.е. ИД из данных в форме. Пробую, получить, вызывая
this.findParentByType('orderEdit').getViewModel().data.singleOrder
но получаю значение по умолчанию, оно у меня null, получается родительская форма не получила ещё свои данные на момент создания таблицы. Как правильно это сделать, может как-то по другому данные родителя получать?

Помимо этого надо чтобы таблица загрузила с сервера данные, вроде надо вызвать store.load() таблицы, но стор таблицы тоже получить не могу, пишет что он пустой, типа вообще не определен. Как бы выходит что и стор тоже ещё не подсоединился к моей таблицы. (У формы свой стор, у таблицы свой.)

Как всё это дело получить? Может быть это надо делать в другом месте, а не в initComponent?

siber-biber 20.06.2015 17:04

в javascript в целом и в extjs в частности сломать всё можно миллионом способов. нужен тест кейс

Пролетарий 20.06.2015 18:30

Тут по моему не то что сломано, а просто наверное что-то не правильно делаю или вообще такое не предусмотрено.

Попробую сформулировать один из вопросов по другому. Если я в store устанавливаю autoLoad: false то как при показе таблицы мне загрузить в неё данные? Т.е. автозагрузка отключена и значит таблица будет пустая. В какой момент и где мне вызвать функцию store.load()?

novikov 20.06.2015 20:36

может быть вызвать store.load() в обработчике события afterrender вашей таблицы. Обработчик можно определить в том числе и внутри initComponent:

this.listeners = {
afterrender: function(grid) { grid.getStore().load(); }
}

Гадать, не хочется. Выложите кусок кода хотя бы...

Пролетарий 20.06.2015 20:37

Кажется нашел как решить проблему загрузки таблицы без автозагрузки. Но очень удивлен тем как это сделано. Я почему-то думал, если определил модель, стор и 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

Я пробовал через это событие (похоже я его угадал, если вы предложили:) ), но там тоже при вызове 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 (Сообщение 375840)
может быть вызвать store.load() в обработчике события afterrender вашей таблицы. Обработчик можно определить в том числе и внутри initComponent:

this.listeners = {
afterrender: function(grid) { grid.getStore().load(); }
}

Гадать, не хочется. Выложите кусок кода хотя бы...


novikov 20.06.2015 21:03

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

novikov 20.06.2015 21:07

хранилище грида можно назначать и во ViewModel, если мне не изменяет память. Там есть спецпараметр stores.

Пролетарий 20.06.2015 21:47

Вложений: 1
К сожалению это не помогло. Возвращает значение, которое у меня указано по умолчанию. Оно при открытии формы заменяется на текущее. Получается данные ещё не загрузились в форму, ну как я думаю.

Вот так выглядит моя 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 (Сообщение 375847)
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
            }
        });
    },


novikov 21.06.2015 09:16

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

Если так, то после клика по строке ордера при создании нового экземпляра формы можно назначить ссылку на выбранную запись во ViewModel через links или linkTo.

У таблицы заметок есть своё хранилище. На мой взгляд, лучше найти этот компонет при помощи up() и down(), затем извлечь его хранилище через getStore() и выполнить фильтрацию filter(), указав в фильтре id выбранного ордера. Благо в обработчике события selectionchange, выполняющем всю эту логику есть информация о выбранной строке.

Поправьте, если я чего недопонял в задаче.


Часовой пояс GMT +3, время: 21:30.