2012-06-12 5 views
10

Я пытаюсь создать класс динамической сетки (где я не знаю никакой информации о столбцах, но они даны из json-ответа, а подставка подготавливается соответственно). Here я нашел именно то, что я искал, однако он дает мне ошибку:Создание динамической сетки с помощью ExtJS

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(); 

}); 

Что я должен сделать, чтобы сделать Симметричный работать?

ответ

9

Это довольно старое сообщение, поэтому в ближайшее время у вас могут появиться дополнительные обходные пути, но эта ошибка возникает из-за того, что у вас нет или fields 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 

Другое дело, что я сделал в прошлом, чтобы иметь ссылки магазин загружен первый, который содержал запись с именем и типом данных для каждого из динамических полей (метаданных). Затем я повторил этот справочный магазин и added a model fieldи определение столбца на каждой итерации, , затем. Я загрузил хранилище сетки, в котором теперь была определена правильная модель данных, и сетка имела бы правильную дефиницию столбцов.

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

UPDATE 13 июня:

Я не пробовал, но я просто наткнулся на this in the 4.1 docs (прокрутите вниз до раздела «Ответ MetaData» в интро). Он описывает использование метаданных в вашем json-ответе, чтобы выполнить именно то, что вы собираетесь использовать с динамической моделью и столбцами сетки.

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

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

+0

«Ответные метаданные». – ilhan

+0

Я считаю, что OP ссылался на документы для Ext.data.reader.Json - в 4.2 a http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.data.reader.Json – Sarge

+0

@Sarge 4.2 не был выпущен во время сообщения – Geronimo

3

ПРИМЕЧАНИЕ: Это дубликат для моего ответа здесь: How do you create table columns and fields from json? (Dynamic Grid). Я просто хотел обратиться к моему окончательному решению во всех вопросах StackOverflow, которые я использовал для решения этой проблемы.

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

Модель: (. Только показывает 2 поля, которые будут во всех ответах JSON-прежнему будут перезаписаны)

Ext.define('RTS.model.TestsModel', { 
    extend: 'Ext.data.Model', 
    alias: 'model.TestsModel', 

    fields: [ 
     { 
      name: 'poll_date' 
     }, 
     { 
      name: 'poller' 
     } 
    ] 
}); 

магазин:

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 должен иметь свойство "МЕТАДАННЫЕ" включен. Он должен определять поля так же, как и для статической модели, и представления, которое обычно определяется для отображения полей.

{ 
    "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" 
     } 
    ] 
} 
Смежные вопросы