2012-06-12 32 views
10

Estoy tratando de hacer una clase Dynamic Grid (donde no conozco ninguna información acerca de las columnas, pero se dan a partir de la respuesta json y el ceñidor se prepara en consecuencia). Here he encontrado exactamente lo que estaba buscando sin embargo, me da un error:Creando una cuadrícula dinámica con ExtJS

me.model is undefined 
me.setProxy(me.proxy || me.model.getProxy()); 
ext-all-debug.js (line 47323) 

He intentado añadir tanto proxy y el modelo, pero no tuvo éxito, seguí recibiendo el mismo error.

Aquí está el código ExtJS que estoy trabajando en:

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

}); 

Lo que tengo que hacer finde para hacer que se ejecute?

Respuesta

9

Esa es una publicación bastante antigua, por lo que es posible que tenga más soluciones provisionales pronto, pero ese error se debe a que no tiene un model config o fields config definido para su tienda. El modelo también deberá definirse dinámicamente si desea que su cuadrícula se cree con datos json solos.

Hasta donde yo sé, la configuración de los campos es bastante indulgente, por lo que puede simplemente configurar esto con un número máximo posible de campos como 20 o 30, pero los nombres de campo tendrían que coincidir con json nombres de campo para que sea utilizable. Es decir. si se utiliza:

var store = new Ext.data.Store({ 
    url: this.storeUrl, 
    reader: new Ext.data.JsonReader(), 
    fields: [ 
     'column1', 
     'column2', 
     'column3', 
     'column4', 
     'column5', 
     // etc 
    ], 

A continuación, sus datos JSON tendría que provenir de la base de datos como:

[{"column1":"data1", "column2":"data2", // etc 

Otra cosa que he hecho en el pasado es tener una tienda de referencia carga por primera vez que contenía un registro con el nombre y el tipo de datos para cada uno de los campos dinámicos (metadatos). Luego itere a través de este almacén de referencia y added a model field la definición de columna en cada iteración, luego Cargué el almacén de la grilla que ahora tenía el modelo de datos correcto definido y la grilla tendría la definición de columna correcta.

Es posible que tenga que hacer algo como si no desea hacer su base de datos devuelve nombres de columna genéricos como cubiertos anteriormente, porque no sé cómo va a cargar los datos en su tienda rejilla inicialmente antes de que dale un modelo de datos para usar.

Actualización 13 de junio:

no he probado todavía, pero me encontré con this in the 4.1 docs (desplácese hacia abajo hasta la sección "Respuesta metadatos" en la introducción). Describe el uso de metadatos en su respuesta json para lograr exactamente lo que busca con un modelo dinámico y columnas de cuadrícula.

Probablemente aún tendrá que hacer la iteración que describí anteriormente una vez que procese los metadatos, pero puede usarla para cortar esa solicitud adicional para obtener los metadatos.

Supongo que si su configuración de campo no cambia con cada solicitud, entonces sería más fácil simplemente hacer la solicitud adicional al principio, pero si desea algo realmente dinámico, esto lo haría.

+0

El "MetaData de respuesta". – ilhan

+0

Creo que OP se refería a los documentos para Ext.data.reader.Json - en 4.2 a http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.data.reader.Json – Sarge

+0

@Sarge 4.2 no se publicó en el momento de la publicación – Geronimo

3

NOTA: Esto es un duplicado de mi respuesta aquí: How do you create table columns and fields from json? (Dynamic Grid). Solo quería abordar mi solución final en todas las preguntas de StackOverflow que utilicé para resolver este problema.

Stackoverflow está lleno de preguntas muy similares a esta. Trabajé con todos ellos y no encontré una solución definitiva. Sin embargo, la mayoría de las respuestas proporcionadas me indicaron la dirección correcta. Yo me dará mejor oportunidad de poner todas esas sugerencias juntos y hacer esto en claro para los demás:

Modelo: (. Sólo se muestran 2 campos que estarán en todas las respuestas JSON todavía será sobrescrito)

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

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

tienda:

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)]); 
    } 
}); 

Vista: (Las columnas se definirán en cada respuesta 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); 
    } 

}); 

controlador: (El controlador hace todo el trabajo en forzar la vista y el modelo a cambios basados ​​en la respuesta 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); 
    } 

}); 

Respuesta JSON: Su respuesta JSON debe tener la propiedad "metadatos" incluido. Debe definir los campos tal como lo haría en un modelo estático y la vista que normalmente se definiría para mostrar los campos.

{ 
    "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" 
     } 
    ] 
} 
Cuestiones relacionadas