2010-11-27 15 views
9

El códigoVuelva a insertar un registro en una extJS tienda

Ext.onReady(
    function() { 
     Ext.QuickTips.init(); 
     Ext.namespace('TimeTracker'); 
     TimeTracker.dataStore = new Ext.data.JsonStore(
      { 
       root: 'timecardEntries', 
       url: 'php/scripts/timecardEntry.script.php', 
       storeId: 'timesheet', 
       autoLoad: true, 
       autoSave: true, 
       writer: new Ext.data.JsonWriter(
        { 
         encode: true 
        } 
       ), 
       fields: [ 
        {name: 'id', type: 'integer'}, 
        {name: 'user_id', type: 'integer'}, 
        {name: 'ticket_id', type: 'integer'}, 
        {name: 'description', type: 'string'}, 
        {name: 'start_time', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 
        {name: 'stop_time', type: 'date', dateFormat: 'Y-m-d H:i:s'}, 
        {name: 'client_id', type: 'integer'}, 
        {name: 'is_billable', type: 'integer'} 
       ] 
      } 
     ); 
     TimeTracker.timeEntryGrid = new Ext.grid.EditorGridPanel(
      { 
       renderTo: Ext.getBody(), 
       store: TimeTracker.dataStore, 
       autoFit: true, 
       height: 500, 
       title: 'Timesheet Entries', 
       tbar: [ 
        { 
         xtype: 'button', 
         text: 'Add Record', 
         iconCls: 'silk-add', 
         handler: function() { 
          var timecardEntry = TimeTracker.timeEntryGrid.getStore().recordType; 
          var tce = new timecardEntry(
           { 
            description: 'New Timesheet Entry', 
            start_time: new Date().format('m/d/Y H:i:s'), 
            is_billable: 0 
           } 
          ) 
           TimeTracker.timeEntryGrid.stopEditing(); 
          var newRow = TimeTracker.dataStore.getCount(); 
          TimeTracker.dataStore.insert(newRow, tce); 
          TimeTracker.timeEntryGrid.startEditing(newRow, 0); 
         } 
        } 
       ], 
       view: new Ext.grid.GridView(
        { 
         autoFill: true 
        } 
       ), 
       colModel: new Ext.grid.ColumnModel(
        { 
         defaults: { 
          sortable: true, 
          editable: true 
         }, 
         columns: [ 
          { 
           id: 'ticket_number', 
           header: 'Ticket #', 
           dataIndex: 'ticket_number', 
           editor: new Ext.form.TextField({allowBlank: true}), 
           renderer: function(value) { 
            return (!value) ? 'N/A' : value; 
           } 
          }, 
          { 
           id: 'description', 
           header: 'Description', 
           dataIndex: 'description', 
           editor: new Ext.form.TextField({allowBlank: false}) 
          }, 
          { 
           id: 'start_time', 
           header: 'Start', 
           dataIndex: 'start_time', 
           renderer: Ext.util.Format.dateRenderer('m/d/Y h:i A'), 
           editor: new Ext.form.DateField({allowBlank: false}) 
          }, 
          { 
           id: 'stop_time', 
           header: 'Stop', 
           dataIndex: 'stop_time', 
           renderer: Ext.util.Format.dateRenderer('m/d/Y h:i A'), 
           editor: new Ext.form.DateField({allowBlank: false}) 
          }, 
          { 
           id: 'client', 
           header: 'Client', 
           dataIndex: 'client_id', 
           renderer: function(value) { 
            return (!value) ? 'N/A' : value; 
           } 
          }, 
          { 
           id: 'billable', 
           header: 'Billable', 
           dataIndex: 'is_billable', 
           renderer: function(value) { 
            return (!value) ? 'No' : 'Yes'; 
           }      
          }, 
          { 
           id: 'actions', 
           header: null, 

           xtype: 'actioncolumn', 
           items: [ 
            { 
             icon: 'assets/images/silk_icons/page_copy.png', 
             iconCls: 'action_icon', 
             handler: function(grid, rowIndex, columnIndex) { 
              // THE PROBLEM STARTS HERE 
              grid.stopEditing(); 
              var newRow = TimeTracker.dataStore.getCount(); 
              recordClone = grid.store.getAt(rowIndex); 
              recordClone.data.start_time = new Date().format('Y-m-d H:i:s'); 
              grid.store.insert(newRow, recordClone); 
              grid.startEditing(newRow, 0); 
             } 
            }, 
            { 
             icon: 'assets/images/silk_icons/page_delete.png', 
             handler: function(grid, rowIndex, columnIndex) { 
              alert('called'); 
             } 
            } 
           ] 
          } 
         ] 
        } 
       ) 
      } 
     ); 
    } 
); 

El objetivo

Cuando el usuario hace clic en el botón 'copia', que tienda de discos se almacena en la memoria, su 'start_time' se establece en la fecha y hora actual, y se vuelve a insertar en la tienda como un nuevo registro

El resultado actual

recibo el siguiente error JS: TypeError no detectada: No se puede leer la propiedad 'datos' de indefinido

Mi pregunta (s)

Para empezar, ni siquiera estoy seguro de si Estoy tomando apropiadamente el registro de datos de la fila actualmente seleccionada. En segundo lugar, no tengo idea de qué significa el mensaje de error que recibo.

Cualquier ayuda es, como siempre, muy apreciada.

Gracias.

Actualización 1

Después de algunos ajustes, esto es lo que ocurrió con (el código modificado para el controlador de botones de copia)

    { 
         id: 'actions', 
         header: null, 

         xtype: 'actioncolumn', 
         items: [ 
         { 
           icon: 'assets/images/silk_icons/page_copy.png', 
           iconCls: 'action_icon', 
           handler: function(grid, rowIndex, columnIndex) { 
            grid.stopEditing(); 
            var newRow = TimeTracker.dataStore.getCount(); 
            var currentRecord = grid.store.getAt(rowIndex); 
            var timecardEntry = grid.store.recordType; 
            tce = new timecardEntry(currentRecord.data); 
            tce.data.start_time = new Date().format('Y-m-d H:i:s'); 
            grid.store.insert(newRow, tce); 
           } 
          }, 
          { 
           icon: 'assets/images/silk_icons/page_delete.png', 
           handler: function(grid, rowIndex, columnIndex) { 
            alert('called'); 
           } 
          } 
         ] 
        } 

Esto es lo que estoy haciendo:

  1. Detener la edición de la cuadrícula
  2. Obtenga el número de registros actualmente en la tienda
  3. Grab el registro actualmente seleccionado y almacenarlo en la memoria
  4. Grab el tipo de registro de la tienda de
  5. Hacer una nueva instancia del tipo de tienda de discos, y pase el objeto de datos del registro seleccionado. El objeto de datos es equivalente al objeto literal si estaba haciendo un nuevo registro a mano (consulte el código original de 'Agregar botón' para obtener detalles)
  6. Modifique el valor start_time del nuevo objeto creado en la fecha y hora de hoy
  7. Insertar registro en la cuadrícula
  8. ¡Feliz momento!

Por favor, critique este código y avíseme si hay una mejor manera de hacerlo. ¡Gracias!

Actualización 2:

       handler: function(grid, rowIndex, columnIndex) { 
            grid.stopEditing(); 
            var recordClone = grid.store.getAt(rowIndex).copy(); 
            Ext.data.Record.id(recordClone); 
            if(recordClone) { 
             grid.store.add(recordClone); 
            } 
           } 

He actualizado el código para utilizar la copia y añadir métodos y funciona. Sin embargo, cuando llamo al método add() obtengo un 'e es un error indefinido' pero cuando actualizo la página, el registro se inserta a pesar del mensaje de error. Ideas?

+0

¿Puede proporcionarnos algunos datos de muestra del script php? – rwilliams

Respuesta

3

Me parece que no está construyendo el objeto tce correctamente. Esta línea es donde se debe establecer el punto de interrupción:

tce = new timecardEntry(currentRecord.data); 

Parece como si estuviera construyendo con éxito un timecardEntry que de alguna manera no es un registro adecuado. Tener un poke en lo que es es la construcción puede ayudar.

Si no es evidente a partir de empuje de esa manera por la que pasa el caño, trata de hacerlo así, como @timdev sugiere:

var store = grid.store, 
    currentRecord = store.getAt(rowIndex), 
    tce; 
tce = currentRecord.copy(); 
tce.set('start_time', new Date().format('Y-m-d H:i:s')); 

if (tce) { 
    store.add(tce); 
} 

(usted debería ser capaz de llamar a grid.store.add(tce) en lugar de insert como estás insertando al final.)

1

Pregunta muy bien escrita. Buena parte del código relevante y una buena explicación de lo que estás atrapado. Desafortunadamente, no veo nada que se destaque.

Su secuencia de comandos se ve sobre todo a la derecha. Estás cerca de estar donde necesitas estar.

A continuación, una respuesta que acabo de tipear, y luego volví a leer su pregunta (y el código), y pensé un poco mejor. Probablemente ya sepas estas cosas, pero está aquí para cualquier otra persona. También es relevante, porque no veo ningún error en la parte relevante de lo que hiciste, por lo que probablemente lo arruines en otro lugar. Las preguntas son: ¿dónde y cómo?

Con suerte alguien menos cansado que estoy va a llegar y encontrar el problema obvio que, mientras tanto, aquí está mi garabato acerca de cómo depurar en Ext y por qué:


que has dejado algo importante fuera , o lo pasé por alto. Ese mensaje de error que mencionó: Uncaught TypeError: Cannot read property 'data' of undefined - donde está sucediendo eso? Parece que no está sucediendo en el código que publicaste, podría estar sucediendo en las entrañas de ExtJS.

Por lo tanto, active FireBug y active la función "romper en error". Haga que su error ocurra, y comience a mirar el panel de "pila" a la derecha (generalmente). La pila te mostrará cómo llegaste a donde estás.

A menos que me falta algo (y ya que estoy ejecutando su código en mi cabeza, muy bien podría ser), es probable que haya algo mal configurado en otra parte que esté causando su error.

Pero como con cualquier programa (y especialmente con ExtJS, en mi experiencia), el depurador es su amigo.

Haga lo siguiente:

  • uso de la versión -debug ext-base.js y ext-all.js (hasta que todas las obras)
  • Uso Firebug, y "romper" en los errores
  • Aprenda a usar el depurador para pasar por el código y para ver los datos en los que está operando.
  • No te rindas cuando te encuentres en las entrañas de ExtJS. Si lo intenta, comenzará a darse cuenta de que está sucediendo WTF, e incluso si no lo comprende todo, comenzará a darle pistas sobre dónde arruinó.
+0

@timdev, gracias por la respuesta. Aquí está la línea exacta que hace que se cuelgue: grid.store.insert (newRow, recordClone); He estado entusiasmado con todo esto y lo único que aprendí es que el error está ocurriendo en lo profundo de extJS. –

+0

Probablemente sea porque no estás clonando correctamente tu registro. Intente cambiar 'recordClone = grid.store.getAt (rowIndex);' a esto: 'recordClone = grid.store.getAt (rowIndex) .copy()'. Posiblemente seguido por 'Ext.data.Record.id (recordClone);' – timdev

+0

Iba a decir esto, de hecho, no está clonando el registro. – Drasill

Cuestiones relacionadas