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, выполняющем всю эту логику есть информация о выбранной строке.

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

khusamov 21.06.2015 11:30

Этот код выглядит странно. Много чего лишнего.

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: 'тут ид родителя таблицы, но как получить?'
            }
        });
    },


Запись
noteStore: null,
не нужна, так как в гриде и так есть store. Незачем делать дубликат.

Запись
this.noteStore = Ext.getStore('JournalApp.store.NoteStore');
вообще не нужна. Все работает и без нее. Нужно store задавать как и полагается: store: {type: "алиас сторе"}

Запись
this.on('render', this.loadStore, this);
не нужна, можно просто store сделать autoload

Проблема " ид родителя таблицы, но как получить?" не решаемая, ибо не виден контекст использования этого кода. Нужна песочница. Сделай те пример.

khusamov 21.06.2015 11:33

Цитата:

(У формы свой стор, у таблицы свой.)
Сделайте пример в песочнице. А то из этой фразы много чего вытекает.

Пролетарий 21.06.2015 12:21

Сначала всё правильно, когда кликаем по "ордерам" в левой части, то открывается закладка "Ордера", где находится перечень всех ордеров в виде таблицы, но там только таблица с ордерами, таблица с "заметками", находится исключительно в самом ордере. Чтобы добраться до таблицы заметок, надо открыть ордер.

Каждая заметка принадлежит конкретному ордеру, поэтому при load() нужно знать ИД ордера, чтобы получить заметки для конкретного ордера, а не все что есть. Так же при редактировании.

Для таблицы "Заметки" я сделал отдельный store, потому что часто будет так что в самом ордере будут добавляться только заметки, а остальные поля не будет затронуты, соответственно нет необходимости из за одной строки, гонять на сервер все 20 полей, которые ещё будет добавлены. (На картинке только малая часть, что я пока добавил.) Мне кажется так правильней в моем случае и даже не думал что возникнут проблемы.

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

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

К сожалению, данные в таблицу заметок должны грузиться при открытии ордера. Т.е. открывается закладка конкретного ордера и таблица заметок заполняется, заметками для открываемого ордера.

Цитата:

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

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

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

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


Пролетарий 21.06.2015 12:41

Цитата:

Сообщение от khusamov (Сообщение 375900)
Этот код выглядит странно. Много чего лишнего.

Возможно, мне сложно судить, но это единственное что заработало, более простые и очевидные способы не работали.
Цитата:

Сообщение от khusamov (Сообщение 375900)
Запись
noteStore: null,
не нужна, так как в гриде и так есть store. Незачем делать дубликат.

А как его получить? Через this.getStore() я получаю стор, но когда вызываю load() то получаю ошибку. А через эту дополнительную переменную всё работает.
Цитата:

Сообщение от khusamov (Сообщение 375900)
Запись
this.noteStore = Ext.getStore('JournalApp.store.NoteStore');
вообще не нужна. Все работает и без нее. Нужно store задавать как и полагается: store: {type: "алиас сторе"}

Я так делаю, если это имеется ввиду, но как я выше написал получаю ошибку. А через это глобальное получение Ext.getStore() по крайней мере в переменной оно есть.
{
        xtype: 'noteGrid',
        fieldLabel: 'Заметки:',
        viewModel: {
            type: 'order'
        },
        bind: {
            store: '{notes}'
        },
    }

Цитата:

Сообщение от khusamov (Сообщение 375900)
Запись
this.on('render', this.loadStore, this);
не нужна, можно просто store сделать autoload

К сожалению от autoload пришлось отказаться, т.к. заметки должны быть получены для конкретного ордера, при открытии этого ордера. А для этого надо знать ИД ордера перед load().

Я когда задумал это дело, то рассчитывал, что при открытии формы, в которую вложена таблица заметок, то при её создании я передам в store фильтр с ИД ордера и затем произойдет autoload и всё будет как в сказке. Но в реальности autoload вызывается при открытии приложения, само собой без нужного ИД, а при открытии формы, где находится таблицы, которую надо загрузить, никакого autoload не происходит. Поэтому весь этот код в initComponent.

khusamov 21.06.2015 13:34

Цитата:

А как его получить? Через this.getStore() я получаю стор, но когда вызываю load() то получаю ошибку. А через эту дополнительную переменную всё работает.
Если делать все правильно, то вызов getStore() не понадобиться.

Этот код:

{
        xtype: 'noteGrid',
        fieldLabel: 'Заметки:',
        viewModel: {
            type: 'order'
        },
        bind: {
            store: '{notes}'
        },
    }



нужно переписать так:

{
        xtype: 'noteGrid',
        fieldLabel: 'Заметки:',
        viewModel: {
            type: 'order',
            stores: { notes: { type: "notes" } }
        },
        bind: {
            store: '{notes}'
        },
    }


Причем до этого должен быть загружен сторе с алиасом "store.notes" (внимание!!!, нужно загружать сам КЛАСС сторе, например достаточно в приложении его прописать в stores или просто через require подгрузить класс).

Цитата:

К сожалению от autoload пришлось отказаться, т.к. заметки должны быть получены для конкретного ордера, при открытии этого ордера. А для этого надо знать ИД ордера перед load().
Автолоад нужен, но грид заметок должен создаваться ПОСЛЕ выбора ордера. После закрытия вкладки ордера грид должен уничтожаться (destroy). Тогда все встанет на свои места. Тогда и автолоад заработает как нужно. Такой вариант во многих примерах сенчи расписан. То есть щелкнули по ордеру - вкладка и грид в ней и вообще все создается на лету, а при закрытии вкладки - все уничтожается.

khusamov 21.06.2015 13:36

Цитата:

Я когда задумал это дело, то рассчитывал, что при открытии формы, в которую вложена таблица заметок, то при её создании я передам в store фильтр с ИД ордера и затем произойдет autoload и всё будет как в сказке. Но в реальности autoload вызывается при открытии приложения, само собой без нужного ИД, а при открытии формы, где находится таблицы, которую надо загрузить, никакого autoload не происходит. Поэтому весь этот код в initComponent.
Еще раз:

1) открытие формы нужно поменять на СОЗДАНИЕ формы и создание всего что в ней

2) автолоад нужен

3) сторе нужно подключать через алиасы, тогда автолоад будет работать не при создании приложения, а при создании формы (аля создании сторе)

khusamov 21.06.2015 13:39

для лучшего понимания создайте код в песочнице

Пролетарий 21.06.2015 13:48

Пытаюсь, но там не меньше сложностей чем в реальном проекте. Уже не один раз пробовал, но пробиться через кучу ошибок не могу. Вот для данной проблемы пробую, но получаю ошибку, которая для меня мало информативна. Если не сложно гляньте, может поможете через проблемы песочницы пробраться, чтобы решить реальную. :)

https://fiddle.sencha.com/#fiddle/p53

Цитата:

Сообщение от khusamov (Сообщение 375907)
для лучшего понимания создайте код в песочнице


khusamov 21.06.2015 14:04

вот исправленный вариант https://fiddle.sencha.com/#fiddle/p55

Файл переименовал orders -> orders.json (точнее прописал URL прямо на вкладке открытого файла, ибо просто переименование почему-то у них не работает...)

Дописал прокси УРЛ:

Ext.define('Fiddle.model.OrderModel', {
    extend: 'Fiddle.model.Base',

    fields: [
        'id', 'description'
    ],
    
    proxy: { // дописал
        url: "orders.json"
    }

});


в классе Fiddle.view.Main дописал:

viewModel: {
        type: 'order',
        stores: { // дописал
            orders: {
                model: "Fiddle.model.OrderModel"
            }
        }
    },


в классе Fiddle.view.Main расскомментировал:

store: '{orders}'

khusamov 21.06.2015 14:05

Цитата:

Пытаюсь, но там не меньше сложностей чем в реальном проекте.
у всех аналогичные проблемы...
но код надо делать маленький, чтобы локализовать ошибку
иначе очень сложно помогать... времени в обрез.

khusamov 21.06.2015 14:12

это устаревшая опция autoCreateViewport
вместо нее mainView надо юзать

Пролетарий 21.06.2015 15:08

Спасибо, буду дальше пример осиливать. Вот только как его маленьким сделать не знаю, тут по сути надо половину функционала в пример перенести, чтобы что-то походило на реальную ситуацию.

Как я понял, основная причина почему не работал пример, это отсутствие прокси с урлом в моделе. Я за основу взял https://fiddle.sencha.com/#fiddle/g56 чтобы смотреть как там сделано и повторять, но у них без прокси работает почему-то. (Ну да ладно, просто мысли в слух.)

Пролетарий 21.06.2015 15:12

Читал я в документации про это, но Sencha Cmd генерирует autoCreateViewport, хотя и взята последняя версия у меня. Пробовал переделать на mainView, но там как всегда непонятные ошибки лезут, поэтому оставил как робот сделал, а то и без этого с каждой ошибкой несколько дней на место топчусь. :)

Цитата:

Сообщение от khusamov (Сообщение 375912)
это устаревшая опция autoCreateViewport
вместо нее mainView надо юзать


khusamov 21.06.2015 15:28

Ясно. С mainView тогда позже разберемся. Мне тоже надо его внедрять скоро в проект. Руки еще не добрались.

Пролетарий 21.06.2015 17:41

Сделал пример, массу всего пришлось нагородить, но все проблемы в файле Note.js. В этом примере то что работает в реальном коде, здесь не работает, поэтому чтобы не было ошибки, закомментировал проблемный участок.

noteStore: null,
    
    initComponent: function() {
        this.callParent();
        this.noteStore = Ext.getStore('Fiddle.store.NoteStore');
        this.on('render', this.loadStore, this);
    },
    
    loadStore: function(grid) {

        var formId = grid.up('orderEdit').getViewModel().data.singleOrder;
        console.log('formId:', formId);
        //console.log(':', grid.up('orderEdit').getViewModel().getData());
        //console.log(grid.getStore());
        
        /*this.noteStore.load({
            scope: this,
            params: {
                orderid: 'тут ид родителя таблицы, но как получить?'
            }
        });*/
    },

Пролетарий 21.06.2015 17:42

Ссылка: https://fiddle.sencha.com/#fiddle/p53

Пролетарий 21.06.2015 19:03

Цитата:

Сообщение от khusamov (Сообщение 375905)
Если делать все правильно, то вызов getStore() не понадобиться.

нужно переписать так:

{
        xtype: 'noteGrid',
        fieldLabel: 'Заметки:',
        viewModel: {
            type: 'order',
            stores: { notes: { type: "notes" } }
        },
        bind: {
            store: '{notes}'
        },
    }


Т.е. помимо определения стора в ViewModel, ещё надо его прописать при определении таблицы?

У меня у формы, содержащей таблицу, есть ViewModel. К которой, я предполагаю будет обращаться и вложенная таблица. Пробовал для вложенной таблицы делать свой ViewModel, но ничего не работало. Когда убрал ViewModel таблицы и стал обращаться к ViewModel формы, то вроде заработало.
[/quote]
Цитата:

Сообщение от khusamov (Сообщение 375905)
Автолоад нужен, но грид заметок должен создаваться ПОСЛЕ выбора ордера. После закрытия вкладки ордера грид должен уничтожаться (destroy). Тогда все встанет на свои места. Тогда и автолоад заработает как нужно. Такой вариант во многих примерах сенчи расписан. То есть щелкнули по ордеру - вкладка и грид в ней и вообще все создается на лету, а при закрытии вкладки - все уничтожается.

Я правильно понял, что вместо определения таблицы как в коде вверху, т.е., среди определения полей в разделе items формы, надо как-то по другому?

Получается нужно в функции initComponent самой формы, создавать вложенную таблицу и тогда автолоад заработает? Тогда по идее можно будет создать что-то вроде переменной во вложенной таблице, куда записать ИД, из создавшей её формы. Хотя попробовал в initComponent самой формы, получить её ИД, то тоже был null. В общем как всегда, непонятки и ошибки всякие. :)

khusamov 21.06.2015 19:49

Цитата:

Т.е. помимо определения стора в ViewModel, ещё надо его прописать при определении таблицы?
Что вы подразумеваете под определением?

khusamov 21.06.2015 19:56

А что вообще должно получиться?
Я вижу пока грид с ордерами:

items:[{
            xtype: 'orderGroup',
            itemId: 'orderGroup_1',
            listeners: {
                vieworder: 'onCreateTab'
            }
        }]


Для чего нужна эта вкладка с таблицей ордеров?

Для чего нужен аккордион слева?

{
        xtype: 'panel',
        layout: {
            type: 'accordion',
            animate: true     
        },    
        collapsible: true,
        ...
    }


В общем нужно описание ФУНКЦИОНАЛЬНОСТИ вашего примера.

Пролетарий 21.06.2015 20:46

Цитата:

Сообщение от khusamov (Сообщение 375970)
Что вы подразумеваете под определением?

Вот определение стора в ViewModel:

Ext.define('JournalApp.view.orders.OrderViewModel', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.order',

    requires: [
        'JournalApp.model.OrderModel',
        //'JournalApp.model.NoteModel' 
        'JournalApp.store.NoteStore' 

    ],

    data: {
        singleOrder: null
    },

    stores: {        
        notes: {
            source: 'JournalApp.store.NoteStore',
        }      
    }

});


Вот определение самой таблицы, где вы рекомендуете добавить ещё раздел стора:
{
        xtype: 'noteGrid',
        fieldLabel: 'Заметки:',
        viewModel: {
            type: 'order',
            stores: { notes: { type: "notes" } }
        },
        bind: {
            store: '{notes}'
        },
    }

Т.е. надо их так дублировать специально?

khusamov 21.06.2015 20:48

Цитата:

Вот определение стора в ViewModel:
ну да, в этом случае нужно столько раз определять store, сколько нужно. А вот класс для store нужен один.

Цитата:

Т.е. надо их так дублировать специально?
ну да, определение класса один раз, а вот на местах создавать через алиас: { type: "алиас" }

Пролетарий 21.06.2015 20:54

Цитата:

Сообщение от khusamov (Сообщение 375974)
А что вообще должно получиться?
Я вижу пока грид с ордерами:
Для чего нужна эта вкладка с таблицей ордеров?

Для чего нужен аккордион слева?

В общем нужно описание ФУНКЦИОНАЛЬНОСТИ вашего примера.

А ну да, забыл описать что надо делать. :)

В таблице ордеров щелкаем два раза на строке, чтобы её отредактировать. В результате чего откроется закладка с формой для редактирования этого ордера. Для каждого ордера создается своя закладка.

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

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

khusamov 21.06.2015 21:04

У вас два файла: orders.json и notes.json
я так понимаю notes это подчиненная таблица, но тогда где в ней внешний ключ? например orderId

khusamov 21.06.2015 21:07

Цитата:

Аккордеон это хвосты, которые остались и я не смог его выпилить из примера, ошибки всякие начинают как всегда лезти, поэтому оставил как есть. Не обращайте на него внимание. Тут самое главное открытие формы редактирования ордера.
в файле Main.js я удалил строки 14-32 и все работает. Зато нет лишнего кода.

Пролетарий 21.06.2015 21:28

Цитата:

Сообщение от khusamov (Сообщение 375984)
У вас два файла: orders.json и notes.json
я так понимаю notes это подчиненная таблица, но тогда где в ней внешний ключ? например orderId

Внешний ключ типа на сервере, а это результат. Внешний ключ будет в урде находиться. Т.е. при загрузке формы, таблица заметок отправляет запрос на сервер с ИД в урле и получает файл notes.json. Я так понимаю ИД внутри самих данных не нужен, т.к. данные всегда будет только для одного ордера, никогда не должно, чтобы при запросе таблицы ордера 1, возвращались заметки ордера 2 или 3.

В примере по сути это не важно. Нужно чтобы таблица заметок загрузилась данными из notes.json, пусть пока будет одно и то же. Ну и как-то получить ИД формы, владеющей этой таблицей.

orders.json и notes.json получаются с сервера независимо и не знают друг о друге, их связывает только то что один из ИД из orders.json, после загрузке в браузер должен быть известен перед отправкой запроса о получении notes.json.

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

Пролетарий 21.06.2015 21:30

Цитата:

Сообщение от khusamov (Сообщение 375985)
в файле Main.js я удалил строки 14-32 и все работает. Зато нет лишнего кода.

Спасибо, то же сделал с примером. Наверное или лишнее цеплял при удалении или наоборот оставлял. Торопился пример сделать.

khusamov 21.06.2015 21:33

1) У вас два вида: Таблица Ордеров и Просмотр Ордера

И для обоих видов вы используете одну и ту же модель вида: order

А по правильному нужно на каждый вид свою модель сделать.

2) Именования нужно привести в порядок. Я уже запарился открывать файлы - каждый раз приходится думать какой файл что хранит в себе.

Например для вида нужно три файла:

Вид.js
ВидModel.js
ВидController.js

где Вид это имя вида

Далее, алиас должен соответствовать имени класса. Например у вас:

есть xtype: 'orderGroup' ему соответствует класс Fiddle.view.OrderGrid

в итоге, я смотрю на orderGroup и ищу аналогичный класс, например Fiddle.view.OrderGroup. Экономьте время на подобные поиски.

Итого примерно вот что должно получиться:

view
 - order
     - Order.js
     - OrderModel.js
     - OrderController.js
 - orders
     - Orders.js
     - OrdersModel.js
     - OrdersController.js
 - notes
     - Notes.js
     - NotesModel.js
     - NotesController.js


Итого три вида. Причем notes это вложенный в order вид.

khusamov 21.06.2015 21:35

Дальше, у вас один store определен. А их ведь два должно!

Сделайте два класса хранилища

Notes.js
Orders.js

и для каждого алиасы notes n orders соответственно

И после этого, в моделях видов можно прописывать {type:"алиас хранилища"}

Пролетарий 21.06.2015 21:36

Можно конечно, насколько я понимаю сделать что-то вроде один ко многим и гонять заметки вместе с ордером, но у меня подобного таблице заметок будет ещё 3 штуки.

Получается ордер создается и заполняется. На этом всё. Больше он мало вероятно будет редактироваться, а вот заметки и ещё 3 подобные таблицы будут добавляться и редактироваться. Они будет состоять из 1-2 полей, а сам ордер из 20. Поэтому хочу сделать независимое обращение к сервера ордера и вложенных в него таблиц.

khusamov 21.06.2015 21:36

Когда вы это сделаете - вы значительно упростите свой код
станет проще в нем что либо искать при анализе
возможно ошибки все исчезнут сами собой - такое тоже иногда бывает


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