LINUX.ORG.RU

extjs Таблицы, модели, маппинг

 ,


0

2

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

Ext.define('myModel', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'WorckGroup', type: 'string' },
        { name: 'Statistics', type: 'auto' },
        { name: 'Specialist', type: 'string', mapping: 'Statistics.Specialist' },
        { name: 'ScallCount', type: 'int', mapping: 'Statistics.SCallCount' },
        { name: 'AverageDuration', type: 'int', mapping: 'Statistics.AverageDuration' }
    ]
});


var store = Ext.create('Ext.data.Store', {
    model: 'myModel',
    proxy: {
        type: 'ajax',
        url: '/omnireports/ajaxgrid',
        reader: {
            type: 'json',
        }
    },
    autoLoad: true
});


var basegrid = Ext.create('Ext.grid.Panel', {
    store: store,
    columns: [
    { header: 'Рабочая группа', width: 200, dataIndex: 'WorckGroup' },
    { header: 'Специалист', dataIndex: 'Specialist' },
    { header: 'Количество обращений', dataIndex: 'ScallCount' },
    { header: 'Среднее время решения', dataindex: 'AverageDuration' }
    ],
});
json
[{"WorckGroup":"3D",
    "Statistics":[
        {"Specialist":"В А","SCallCount":64,"AverageDuration":0.1136067},
        {"Specialist":"К Т","SCallCount":170,"AverageDuration":0.1045816}]}]

Уже понял в чем ошибка. Пытался разобрать массив Statistics как переменную, невнимателен. А вот теперь интереснее - как же все таки правильно вывести данные в таблицу.

matroskin
() автор топика
[
{"WorckGroup":"3D",
    "Statistics":[
    {"Specialist":"В А","SCallCount":64,"AverageDuration":0.1136067},
    {"Specialist":"К Т","SCallCount":170,"AverageDuration":0.1045816}]
{"WorckGroup":"SD",
    "Statistics":[
    {"Specialist":"B A","SCallCount":197,"AverageDuration":0.1364689}]
}
]

Прошу прощения, привел недостаточный JSON в начале темы.

matroskin
() автор топика

У тебя говно вместо модели, очевидно.

Модель ExtJS - это одна запись из той хрени, с которой кормится твой стор. А у тебя в модели в перемешку поля, которые одни на ответ (WorckGroup) и которых много (Statistics).

Можно в принципе выставить root на Statistics, но WorkGroup ты тогда не запихнёшь в запись (по крайней мере я не знаю как такое устроить.

Самая мякотка с наполнением записей происходит тут: http://docs.sencha.com/extjs/4.1.1/#!/api/Ext.data.reader.Json

Возможно его можно подхачить, чтобы было то, что нужно. В крайнем случае можно подсунуть свой очень специальный reader в proxy.

А с гридом всё просто - херачишь рабочую модель со стором, в гриде указываешь на каждую колонку dataIndex с названием поля из модели и усё будет хорошо.

anonymous
()
Ответ на: комментарий от matroskin

И ещё совет: если можешь менять формат, отдаваемый сервером - разверни структуру в плоский набор записей, без группировки по «WorckGroup». Тогда с бубном плясать не придётся. Чем ближе ответ к тому, что отображаешь, тем лучше. ExtJS мощная библиотека, но если хочется странного, то ты остаёшься наедине с её исходниками и местами неполной документацией.

anonymous
()
Ответ на: комментарий от matroskin

JSON для AJAX это что-то вроде presentation model, избыточности там может быть сколько угодно, ящитаю.

Лучше покажи как решил проблему, больше всего интересует модель и стор.

anonymous
()
Ответ на: комментарий от anonymous

А вот и не решил, пока еще думаю. Вижу 2 варианта. Простой - представить, как TreeGrid. Сложнее - написать свой метод, который из древовидной структуры будет делать мне плоский набор. Пока не понимаю, как добраться к переменным из стора. js и extjs использую вообще не больше недели.

matroskin
() автор топика
Ответ на: комментарий от matroskin

Расширил стандартный JsonReader, чтобы перед разбором записей разворачивал структуру в плоскую таблицу. Код не проверял, писал в блокноте. Если тебе по всей этой байде потом нужна будет ещё сортировка по всем полям и пагинация, то в любом случае придётся ответ от сервера в плоский вид привести.

StatisticsFlatJsonReader = Ext.extend(Ext.data.JsonReader, {
    readRecords: function(data) {        
        var arraysOfRecords = Ext.Array.map(data, function (groupRecord) {
            var group = groupRecord['WorckGroup'];
            var rawRecords = groupRecord['Statistics'];
            Ext.Array.each(rawRecords, function (rawRecord) {
                rawRecord['WorckGroup'] = group;
            });
            return rawRecords;
        });                
        return StatisticsFlatJsonReader.superclass.readRecords.call(this, Ext.Array.merge(arraysOfRecords));
    }
 
});
Ext.data.ReaderMgr.registerType('statisticsflatjson', StatisticsFlatJsonReader);

Ext.define('myModel', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'WorckGroup', type: 'string' },        
        { name: 'Specialist', type: 'string' },
        { name: 'ScallCount', type: 'int' },
        { name: 'AverageDuration', type: 'float' }
    ]
});


var store = Ext.create('Ext.data.Store', {
    model: 'myModel',
    proxy: {
        type: 'ajax',
        url: '/omnireports/ajaxgrid',
        reader: {
            type: 'statisticsflatjson'
        }
    },
    autoLoad: true
});


var basegrid = Ext.create('Ext.grid.Panel', {
    store: store,
    columns: [
    { header: 'Рабочая группа', width: 200, dataIndex: 'WorckGroup' },
    { header: 'Специалист', dataIndex: 'Specialist' },
    { header: 'Количество обращений', dataIndex: 'ScallCount' },
    { header: 'Среднее время решения', dataindex: 'AverageDuration' }
    ],
});

anonymous
()
Ответ на: комментарий от anonymous

Спасибо огромное! Но я решил пойти другим путем.
Читал документацию по деревьям и treegrid, смотрел примеры. Выяснил, что дочерние элементы должны иметь имя 'children' или нужно менять свойство ридера defaultRootProperty на имя поля, содержащего дочерние элементы, более того - dataindex для выводимых данных так же должны быть одинаковые. Но тут еще проблема - а если вложенность большая и эти имена различаются? Попробовал написать новую модель ко всему имеющемуся, вывод в консоль firebug корректный, маппинг работает нормально, но... Но вот дерево не строится. Строится, но при попытке его развернуть вместо дочерних элементов я вижу опятть загруженное дерево.
Код моделей, теста и json

[{"WorkGroup":"Группа поддержки 3D",
        "Statistic":[
            {"Specialist":"Александр Константинович",
            "SCallCount":64,"AverageDuration":0.1136067,"leaf":true},
            {"Specialist":"Татьяна Алексеевна",
            "SCallCount":172,"AverageDuration":0.1058641,"leaf":true},
            {"Specialist":"Алексей Валентинович",
            "SCallCount":72,"AverageDuration":0.4269940,"leaf":true}]},
    {"WorkGroup":"Группа поддержки сервиса КСУП",
        "Statistic":[
            {"Specialist":"Руслан Евгеньевич",
            "SCallCount":67,"AverageDuration":0.1090698,"leaf":true},
            {"Specialist":"Алексей Алексеевич",
            "SCallCount":17,"AverageDuration":0.1125816,"leaf":true},
            {"Specialist":"Анна Владимировна",
            "SCallCount":172,"AverageDuration":0.0632347,"leaf":true},
            {"Specialist":"Мирослав Александрович",
            "SCallCount":315,"AverageDuration":0.0945766,"leaf":true},
            {"Specialist":"Николай Владимирович",
            "SCallCount":7,"AverageDuration":0.2342261,"leaf":true}]},
        ]}
Модель
Ext.define('WorkGroupModel', {
   extend: 'Ext.data.Model',
    proxy: {
       type: 'rest',
       url: '/omnireports/ajaxgrid',
       reader: {
          type: 'json'
       }
     },
     fields: [{ name: 'text', mapping: 'WorkGroup' }],
     hasMany: { name: 'children', model: 'StatisticModel', associationKey: 'Statistic' }
})

Ext.define('StatisticModel', {
  extend: 'Ext.data.Model',
    fields: [
      { name: 'text', mapping: 'Specialist' },
      'SCallCount','AverageDuration',
      { name: 'leaf', defaultVale: true }
    ]
})
Тест и выхлоп в консоль
WorkGroupModel.load(1, {
  success: function (wg) {
    console.log("WorkGroup: " + wg.get('text'));
      wg.children().each(function (specialist) {
        console.log("Specialist: " + specialist.get('text') + "\n leaf: " + specialist.get('leaf'));
      });
  }
});

/////////
WorkGroup: Группа поддержки 3D
Specialist: Александр Константинович
 leaf: true
Specialist: Татьяна Алексеевна
 leaf: true
Specialist: Алексей Валентинович
 leaf: true
И вот код treegrid, определен только один столбец
Ext.define('basegrid', {
    extend: 'Ext.tree.Panel',
    xtype: 'tree-grid',
    title: 'Core Team Projects',
    height: 300,
    useArrows: true,
    rootVisible: false,
    multiSelect: true,
    singleExpand: false,
    initComponent: function () {
        this.width = 500;
        Ext.apply(this, {
            store: new Ext.data.TreeStore({
                model: WorkGroupModel,
                proxy: {
                    type: 'rest',
                    url: '/omnireports/ajaxgrid',
                    reader: {
                        type: 'json'
                    }
                },
                    autoLoad: true,
                    folderSort: true
                }),
            columns: [{
                xtype: 'treecolumn',
                text: 'Task',
                flex: 2,
                sortable: true,
                dataIndex: 'text'
            }]
        });
        this.callParent();
    }
});
Скрин результата https://ps.vk.me/c538515/u155966612/doc/20cd60c2c4c6/Bezymyanny.png

matroskin
() автор топика
Ответ на: комментарий от anonymous

И думаю таки перейти на плоскую выдачу с сервера. Но спортивный интерес не дает этого сделать.

matroskin
() автор топика
Ответ на: комментарий от matroskin

а если вложенность большая и эти имена различаются?

Пиши свои treepanel и treestore.

Дефолтные реализации предполагают, что все узлы дерева логически единообразны. Рендер можно кастомизовать в зависимости на наполнения узла, а вот модель должна быть одна (причём лучше, если она реализует NodeInterface - по другому с ExtJS 4.1.1 у нас не заводилось). Ein treepanel, ein treestore, ein model!

ExtJS он как государство из фильма «Бразилия»: или ты прогибаешься, или огребаешь. У нас за год разработки, на исправление багов ExtJS и перепил того, что когда-то сделали «неканонично», ушёл почти месяц работы.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.