Создание динамической сетки с помощью ExtJS
Я пытаюсь создать класс Dynamic Grid (где я не знаю никакой информации о столбцах, но они даны из json-ответа, и подглава подготавливается соответственно). Здесь Я нашел именно то, что искал, но это дает мне ошибку:
me.model is undefined
me.setProxy(me.proxy || me.model.getProxy());
ext-all-debug.js (line 47323)
Я попытался добавить прокси и модель, но мне не удалось, я все равно получал ту же ошибку.
Вот код ExtJS, над которым я работаю:
// ExtJS 4.1
Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', '../extjs-4.1.0/examples/ux');
Ext.require([
'Ext.grid.*',
'Ext.data.*', ]);
Ext.define('DynamicGrid', {
extend: 'Ext.grid.GridPanel',
storeUrl: '',
enableColumnHide: true,
initComponent: function () {
var store = new Ext.data.Store({
url: this.storeUrl,
reader: new Ext.data.JsonReader(),
autoLoad: true,
scope: this,
listeners: {
scope: this,
metachange: function (store, meta) {
if (typeof (store.reader.jsonData.columns) === 'object') {
var columns = [];
/**
* Adding RowNumberer or setting selection model as CheckboxSelectionModel
* We need to add them before other columns to display first
*/
if (this.rowNumberer) {
columns.push(new Ext.grid.RowNumberer());
}
if (this.checkboxSelModel) {
columns.push(new Ext.grid.CheckboxSelectionModel());
}
Ext.each(store.reader.jsonData.columns, function (column) {
columns.push(column);
}); // Set column model configuration
this.getColumnModel().setConfig(columns);
this.reconfigure(store, this.getColumnModel());
}
}
}
});
var config = {
title: 'Dynamic Columns',
viewConfig: {
emptyText: 'No rows to display'
},
loadMask: true,
border: false,
stripeRows: true,
store: store,
columns: []
}
Ext.apply(this, config);
Ext.apply(this.initialConfig, config);
DynamicGrid.superclass.initComponent.apply(this, arguments);
},
onRender: function (ct, position) {
this.colModel.defaultSortable = true;
DynamicGrid.superclass.onRender.call(this, ct, position);
}
});
Ext.onReady(function () {
Ext.QuickTips.init();
var grid = Ext.create('DynamicGrid', {
storeUrl: 'http://300.79.103.188/ApplicationJs/jsontest.json'
});
var depV = Ext.create('Ext.Viewport', {
title: 'Departman Tanımları',
layout: 'fit',
items: grid
}).show();
});
Что мне нужно сделать, чтобы запустить его?
Ответы
Ответ 1
Это довольно старое сообщение, так что у вас может появиться больше обходных решений, но эта ошибка возникает из-за отсутствия конфигурации или поля config, определенные для вашего магазина. Модель также должна быть определена динамически, если вы хотите, чтобы ваша сетка была создана только с данными json.
Насколько я знаю, конфигурация полей довольно прощающая, поэтому вы можете просто установить это с максимально возможным количеством полей, например, 20 или 30 или около того, но имена полей должны были бы совпадать с json имена полей для использования. То есть если вы используете:
var store = new Ext.data.Store({
url: this.storeUrl,
reader: new Ext.data.JsonReader(),
fields: [
'column1',
'column2',
'column3',
'column4',
'column5',
// etc
],
Затем ваши данные json должны будут поступать из базы данных, например:
[{"column1":"data1", "column2":"data2", // etc
Еще одна вещь, которую я делал в прошлом, - сначала загрузить загрузочный магазин, в котором содержится запись с именем и типом данных для каждого из динамических полей (метаданных). Затем я повторил этот справочный магазин и добавил поле модели и определение столбца на каждой итерации, затем загрузил хранилище сетки, в котором теперь была определена правильная модель данных, и сетка будет иметь правильную разметку столбца.
Возможно, у вас есть что-то подобное, если вы не хотите, чтобы ваша база данных возвращала общие имена столбцов, как описано выше, потому что я не знаю, как вы сначала загрузите данные в хранилище сетки, прежде чем дать им используемой модели данных.
ОБНОВЛЕНИЕ 13 июня:
Я еще не пробовал, но я просто встретил это в документах 4.1 (прокрутите вниз до "MetaData ответа" раздел во вступлении). Он описывает использование метаданных в вашем json-ответе, чтобы выполнить именно то, что вы собираетесь использовать с динамической моделью и столбцами сетки.
Вероятно, вам все равно придется выполнить итерацию, описанную выше, после обработки метаданных, но вы можете использовать ее для вырезания этого дополнительного запроса для получения метаданных.
Я полагаю, если ваша конфигурация поля не изменится с каждым запросом, тогда было бы проще просто выполнить дополнительный запрос в начале, но если вы хотите что-то действительно динамическое, это сделало бы это.
Ответ 2
ПРИМЕЧАНИЕ. Это дубликат моего ответа здесь: Как вы создаете столбцы и поля таблицы из json? (Динамическая сетка). Я просто хотел адресовать свое окончательное решение во всех вопросах StackOverflow, которые я использовал для решения этой проблемы.
Stackoverflow усеян вопросами, очень похожими на этот. Я работал над ними и не нашел окончательного решения. Однако большинство предоставленных ответов указали мне в правильном направлении. Я сделаю все возможное, чтобы соединить все эти предложения и сделать это понятным для других:
Модель: (Показывает только 2 поля, которые будут во всех ответах JSON. Все еще будут перезаписаны)
Ext.define('RTS.model.TestsModel', {
extend: 'Ext.data.Model',
alias: 'model.TestsModel',
fields: [
{
name: 'poll_date'
},
{
name: 'poller'
}
]
});
Store:
Ext.define('RTS.store.TestsStore', {
extend: 'Ext.data.Store',
alias: 'store.TestsStore',
model: 'RTS.model.TestsModel',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
proxy : {
type : 'ajax',
url : 'tests.php',
reader : {
type : 'json',
root : 'tests',
successProperty : 'success'
}
},
storeId: 'tests-store'
}, cfg)]);
}
});
Вид: (столбцы будут определены в каждом ответе JSON)
Ext.define('RTS.view.TestsView', {
extend: 'Ext.grid.Panel',
alias: 'widget.TestsView',
id: 'tests-view',
title: 'Tests',
emptyText: '',
store: 'TestsStore',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
viewConfig: {
},
columns: [
]
});
me.callParent(arguments);
}
});
Контроллер: (Контроллер выполняет всю работу по форсированию представления и модели в зависимости от ответа JSON).
Ext.define('RTS.controller.TestsController', {
extend: 'Ext.app.Controller',
alias: 'controller.TestsController',
stores: [
'TestsStore'
],
models: [
'TestsModel'
],
views: [
'TestsView'
],
init: function(application) {
// When store changes, trigger an event on grid
// to be handled in 'this.control'.
// NOTE : Ext JS does not allow control of
// non-component events.
// Ext JS 4.2 beta will allow the controller
// to detect non-component changes and handle them
var testsStore = this.getStore('TestsStore');
testsStore.on("metachange", metaChanged, this);
function metaChanged(store, meta) {
var grid = Ext.ComponentQuery.query('TestsView')[0];
grid.fireEvent('metaChanged', store, meta);
};
this.control({
"TestsView": {
metaChanged: this.handleStoreMetaChange
}
});
},
/**
* Will update the model with the metaData and
* will reconfigure the grid to use the
* new model and columns.
*/
handleStoreMetaChange: function(store, meta) {
var testsGrids = Ext.ComponentQuery.query('TestsView')[0];
testsGrids.reconfigure(store, meta.columns);
}
});
Ответ JSON:
В вашем ответе json должно быть включено свойство metaData. Он должен определять поля так же, как и для статической модели и представления, которое обычно определяется для отображения полей.
{
"success": true,
"msg": "",
"metaData": {
"fields": [
{
"name": "poller"
},
{
"name": "poll_date"
},
{
"name": "PING",
"type": "int"
},
{
"name": "SNMP",
"type": "int"
},
{
"name": "TELNET",
"type": "int"
},
{
"name": "SSH",
"type": "int"
},
{
"name": "all_passed"
}
],
"columns": [
{
"dataIndex": "poller",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "Poller"
},
{
"dataIndex": "poll_date",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "Poll Date"
},
{
"dataIndex": "PING",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "PING",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "SNMP",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "SNMP",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "TELNET",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "TELNET",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "SSH",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "SSH",
"renderer": "RenderFailedTests"
},
{
"dataIndex": "all_passed",
"flex": 1,
"sortable": false,
"hideable": false,
"text": "All Passed",
"renderer": "RenderFailedTests"
}
]
},
"tests": [
{
"poller": "CHI",
"poll_date": "2013-03-06",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "DAL",
"poll_date": "2013-03-06",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "CHI",
"poll_date": "2013-03-04",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "DAL",
"poll_date": "2013-03-04",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
},
{
"poller": "CHI",
"poll_date": "2013-03-01",
"PING": "1",
"SNMP": "0",
"TELNET": "1",
"SSH": "0",
"all_passed": "0"
}
]
}