Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   Отображение связанных данных ( association, ExtJS 4 ) (https://javascript.ru/forum/extjs/23453-otobrazhenie-svyazannykh-dannykh-association-extjs-4-a.html)

Warlus 24.11.2011 09:36

Отображение связанных данных ( association, ExtJS 4 )
 
Здравствуйте. Начинаю изучать ExtJS 4, возник следующий вопрос. Пусть имеется две связанных модели данных. Например:

Ext.define('Street.model.AreaModel',{
	extend: 'Ext.data.Model',
	
	fields: [ 'id', 'region_id', 'code', 'name', 'shortName', 'postIndex' ],
	
	proxy: {
		type: 'ajax',
		url: 'data/regions.json',
		reader: {
			type: 'json',
			root: 'areas'
		}
	}
	
	
});

Ext.define('Street.model.TownModel',{
	extend: 'Ext.data.Model',
	
	fields: [ 'id', 'region_id', 'area_id', 'code', 'name', 'shortName', 'postIndex' ],
	
	associations: [

		{ type: 'belongsTo', 
		  model: 'Street.model.AreaModel', 
		  foreignKey: 'area_id', 
		  getterName: 'getArea', 
		  associationKey: 'areas' }

	],
        
        proxy: {
		type: 'ajax',
		url: 'data/regions.json',
		reader: {
			type: 'json',
			root: 'towns'
		}
	}

});


Соответственно вторая модель связана с первой посредством belongsToAssociation. Хотелось бы узнать каким образом нужно создать стораджи, чтобы в Ext.grid.Panel типа такой:

Ext.define('Street.view.town.Grid',{
	extend: 'Ext.grid.Panel',
	alias: 'widget.towngrid',
	
	title: 'Города',
	
	store: 'TownStore',	
	features: [{ ftype: 'grouping' }],	
	
	columns: [
		{ header: 'Код', dataIndex: 'code' },
		{ header: 'Наименование', dataIndex: 'name'},
		{ header: 'Сокр. наименование', dataIndex: 'shortName' },
		{ header: 'Индекс', dataIndex: 'postIndex' },
                { header: 'Район', ???? }

	]
});


в столбец "Район" загрузить связанный данные( напрмер поле name модели AreaModel) по area_id из модели TownModel?

Спасибо за внимание! :)

Bkmz_1_ 24.11.2011 14:44

Ты хочешь отфильтровать данные? Чтобы показать города одного района?

Warlus 24.11.2011 15:16

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

Я предположил, что в сущностях ExtJS нужно создать две модели данных "Районы" и "Города", и задать между ними связь( association ), типа belongsTo (каждый город относится к одному району). Далее я создал очень простые store соответственно для городов и для районов:
Ext.define('Street.store.AreaStore', {
	extend: 'Ext.data.Store',
	storeId: 'AreaStore',
	
	model: 'Street.model.AreaModel',
});

Ext.define('Street.store.TownStore', {
	extend: 'Ext.data.Store',
	storeId: 'TownStore',
	
	model: 'Street.model.TownModel',
});


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

скорей всего нужно использовать свойство "renderer" при инициализации колонки "Район" и в нем задать функцию, которая каким, то образом извлекет нужные данные. Что-то типа:
columns:[...

{ header: 'Район', 
		  dataIndex: 'area_id', 
		  renderer: function(value, meta, model) {
		  	return model.getArea(function(area){
		  		return area.get('name');
		  		});
		  	}
}

... ]


Но так не работает, печатает в столбце "function () {return this.constructor.apply (this, arguments);}". Вообщем ломаю голову...

Bkmz_1_ 24.11.2011 15:35

А можно посмотреть на regions.json ?

Warlus 24.11.2011 15:41

Цитата:

Сообщение от Bkmz_1_ (Сообщение 138765)
А можно посмотреть на regions.json ?

конечно.
{
'areas':[
		{ 'id':1, 'code': 1, 'name':'Area1', 'shortName':'a1', 'postIndex': '123456' },
		{ 'id':2, 'code': 1, 'name':'Area2', 'shortName':'a2', 'postIndex': '123456' },
		{ 'id':3, 'code': 1, 'name':'Area3', 'shortName':'a3', 'postIndex': '123456' },
		{ 'id':4, 'code': 1, 'name':'Area4', 'shortName':'a4', 'postIndex': '123456' }	],
	
'towns':[
		{ 'id':1, 'area_id': 2, 'code': 1, 'name':'Town1', 'shortName':'t1', 'postIndex':'123456' },
		{ 'id':2, 'area_id': 1, 'code': 1, 'name':'Town2', 'shortName':'t2', 'postIndex':'123456' },
		{ 'id':3, 'area_id': 3, 'code': 1, 'name':'Town3', 'shortName':'t3', 'postIndex':'123456' },
		{ 'id':4, 'area_id': 4, 'code': 1, 'name':'Town4', 'shortName':'t4', 'postIndex':'123456' },
		{ 'id':5, 'area_id': 2, 'code': 1, 'name':'Town5', 'shortName':'t5', 'postIndex':'123456' },
	]
}

Bkmz_1_ 24.11.2011 17:17

Может проще собрать один 'towns': [] со всеми данными и не мучатся с объединениями данных?

Warlus 25.11.2011 11:47

Походу так и придется сделать. Но все равно хотелось бы понять как пользоваться асоциациями? они ведь существуют как раз для создания реляционной модели данных приложения? Если кто понял суть, объясните пожалуйста, документация впринципе конечно вроде бы все доходчиво объясняет, но вот в структуре MVC заставить это работать не получается... Конкретно например непонятно, что возвращает автоматически генерируемая getter-функция belongsTo ассоциации, по идее она должна возвращать Ext.data.Model в которую с помощью указанного прокси должны парсится нужные данные, но вот почему-то этого не происходит.

jowee 25.11.2011 16:53

Задавался недавно подобным вопросом, через ассоциации так и не получилось выбрать данные. В итоге, в рендерере сделал выборку из нужного стора
renderer: function(value){
                orderStore.clearFilter();
                var idx = orderStore.find('id', value);
                     if (idx != -1) {
                           var description = orderStore.getAt(idx).get('description');
                           return description;
                    } else return '...';
}

Bkmz_1_ 25.11.2011 16:54

Ну у тебя как минимум не правильно построен json

http://docs.sencha.com/ext-js/4-0/#!...associationKey

{
    "groups": {
        "id": 10,
        "parent_id": 100,
        "name": "Main Group",
        "parent_group": {
            "id": 100,
            "parent_id": null,
            "name": "Parent Group"
        },
        "child_groups": [{
            "id": 2,
            "parent_id": 10,
            "name": "Child Group 1"
        },{
            "id": 3,
            "parent_id": 10,
            "name": "Child Group 2"
        },{
            "id": 4,
            "parent_id": 10,
            "name": "Child Group 3"
        }]
    }
}

Sogl 09.11.2016 03:17

А для ExtJS 6 есть толковый материал как вывести ассоциированные данные в гриде? Перерыл форум Сенчи и в основном одни вопросы вижу и проблемы, а примеров живых нет.

Вот с SO нормальный пример:
http://stackoverflow.com/a/16616228/4827198
Только данные там синтетические у него и УЖЕ полученные (тип прокси - memory), вопрос нормально не раскрыт.

Выглядит все так, будто реально проще уже с JOIN'ом данные выводить или денормализацию делать (+1 поле в БД), чем на ExtJS рисовать ассоциации.


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