2010-11-27 23 views
9

Le coderéinsérant un enregistrement dans un magasin ExtJS

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

L'objectif

Lorsque l'utilisateur clique sur le bouton « copier », ce disque de stockage est stocké dans la mémoire, son 'start_time' est réglé sur la date et l'heure actuelles, et il est réinséré dans le magasin en tant que nouvel enregistrement

Le résultat actuel

Je reçois l'erreur JS suivant: Uncaught TypeError: Impossible de lire la propriété 'données' undefined

Ma question (s)

Pour commencer, je ne suis même pas sûr si je saisis correctement l'enregistrement de la ligne actuellement sélectionnée. Deuxièmement, je n'ai aucune idée de ce que signifie le message d'erreur que je reçois.

Toute aide est, comme toujours, très appréciée.

Merci.

Update 1

Après quelques ajustements, voici ce que je suis venu avec (ce code modifié pour le gestionnaire de bouton de copie)

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

Voici ce que je fais:

  1. Arrêter d'éditer la grille
  2. Obtenir le nombre de fiches actuellement dans la boutique
  3. Prenez le record actuellement sélectionné et le stocker dans la mémoire
  4. Prenez le type d'enregistrement du magasin
  5. Faire une nouvelle instance du type d'enregistrement du magasin, et passer dans l'objet de données de l'enregistrement sélectionné. L'objet de données est équivalent au littéral de l'objet si vous créez un nouvel enregistrement à la main (voir le code d'origine 'ajouter un bouton' pour plus de détails)
  6. Modifiez la valeur start_time du nouvel objet créé à la date et à l'heure d'aujourd'hui
  7. Insérer un enregistrement dans la grille
  8. Bon temps!

Veuillez critiquer ce code et faites-moi savoir s'il y a une meilleure façon de le faire. Merci!

Mise à jour 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); 
            } 
           } 

Je mis à jour le code à utiliser la copie et ajouter des méthodes et fonctionne. Cependant, lorsque j'appelle la méthode add(), j'obtiens un 'e is undefined error' mais quand je rafraîchis la page, l'enregistrement est inséré malgré le message d'erreur. Des idées?

+0

Pouvez-vous fournir des exemples de données du script PHP? – rwilliams

Répondre

3

Il me semble qu'il ne construit pas correctement l'objet tce. Cette ligne est l'endroit où vous devez définir votre point d'arrêt:

tce = new timecardEntry(currentRecord.data); 

Il semble que c'est la construction avec succès un timecardEntry qui est en quelque sorte pas un bon dossier. Avoir un poke à ce que est construire peut aider.

Si ce n'est pas évident de piquer de cette façon pourquoi il est le bec, essayez de le faire comme ça, comme @timdev suggère:

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

(vous devriez être en mesure d'appeler grid.store.add(tce) au lieu de insert comme vous insérez à la fin.

1

Question très bien écrite. Bon morceau de code pertinent, et une bonne explication de ce que vous êtes coincé. Malheureusement, je ne vois rien qui se démarque.

Votre script semble principalement correct. Vous êtes proche d'être là où vous devez être. Ci-dessous est une réponse que je viens de taper, puis relu votre question (et le code), et pensé un peu mieux de. Vous connaissez probablement déjà ce genre de choses, mais c'est ici pour quelqu'un d'autre. C'est aussi pertinent, parce que je ne vois pas d'erreurs dans la partie pertinente de ce que vous avez fait, donc vous l'avez probablement soufflé ailleurs. Les questions sont: où et comment?

Espérons que quelqu'un moins épuisé que je suis va venir et trouver le problème évident, en attendant, voici mon grimoire sur le débogage dans Ext et pourquoi:


Vous avez laissé quelque chose d'important sur , ou l'a négligé. Ce message d'erreur que vous avez mentionné: Uncaught TypeError: Cannot read property 'data' of undefined - est-ce que cela se passe? Il semble que ça ne se passe pas dans le code que vous avez posté, ça pourrait très bien arriver dans les entrailles d'ExtJS. Donc, lancez FireBug, et activez la fonction "break on error". Faites votre erreur et commencez à regarder le volet "pile" sur la droite (généralement). La pile va vous montrer comment vous êtes arrivé là où vous êtes.

À moins que je ne manque quelque chose (et puisque je suis juste en train d'exécuter votre code dans ma tête, je le suis très bien), il y a probablement quelque chose de mal configuré ailleurs qui cause votre bug.

Mais comme avec n'importe quel programme (et surtout avec ExtJS, dans mon expérience), le débogueur est votre ami.

Pour ce faire:

  • Utilisez la version -debug de-ext base.js et ext-all.js (jusqu'à tous les)
  • Utilisez Firebug et "briser sur les erreurs"
  • Apprenez à utiliser le débogueur pour parcourir le code et pour regarder les données sur lesquelles vous travaillez. N'abandonnez pas quand vous vous trouvez dans les entrailles de ExtJS. Si vous essayez, vous commencerez à avoir une idée de WTF qui se passe, et même si vous ne comprenez pas tout, il commencera à vous donner des indices sur l'endroit où vous avez foiré.
+0

@timdev, merci pour la réponse. Voici la ligne exacte qui provoque son blocage: grid.store.insert (newRow, recordClone); J'ai tiré sur l'enfer de cette chose et la seule chose que j'ai apprise est que l'erreur se produit en profondeur dans extJS. –

+0

C'est probablement parce que vous ne clonez pas correctement votre dossier. Essayez de changer 'recordClone = grid.store.getAt (rowIndex);' à ceci: 'recordClone = grid.store.getAt (rowIndex) .copy()'. Peut-être suivi de 'Ext.data.Record.id (recordClone);' – timdev

+0

J'allais dire ceci, en effet, vous ne clonez pas le dossier. – Drasill