2010-11-27 72 views
9

代碼重新插入記錄到一個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'); 
             } 
            } 
           ] 
          } 
         ] 
        } 
       ) 
      } 
     ); 
    } 
); 

目標

當用戶點擊了「複製」鍵,該商店記錄被存儲到存儲器中,其'start_time'設置爲當前日期和時間,並將其重新插入商店作爲新記錄

當前結果

我收到以下JS錯誤:遺漏的類型錯誤:如果無法讀取未定義

我的問題(S)

對於初學者來說,我不是財產「數據」,甚至相信我抓住當前所選行的數據記錄。其次,我不知道我收到的錯誤信息的含義。

任何幫助,一如既往,高度讚賞。

謝謝。

更新1

一些調整後,這裏就是我想出了(複印按鈕處理這個修改後的代碼)

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

下面是我在做什麼:

  1. 停止編輯網格
  2. 獲取當前在商店中的記錄數
  3. 抓鬥當前選擇的記錄並將其存儲在存儲器
  4. 抓鬥從商店
  5. 記錄類型使商店記錄類型的新實例,並且從所選擇的記錄在所述數據對象傳遞。如果您手動創建新記錄,則數據對象相當於對象字面值(請參閱我的原始「添加按鈕」代碼以瞭解詳細信息)
  6. 將創建的新對象的start_time值更改爲今天的日期和時間
  7. 將記錄插入網格
  8. 歡樂時光!

請批評這段代碼,讓我知道是否有更好的方法來做到這一點。謝謝!

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

我更新的代碼使用複製和添加方法和它的工作。但是,當我調用add()方法時,我得到'e是未定義的錯誤',但是當我刷新頁面時,儘管出現了錯誤消息,但仍然插入了記錄。想法?

+0

你能否提供一些來自php腳本的示例數據? – rwilliams 2010-11-27 04:07:29

回答

3

在我看來,它不正確構造tce對象。這條線是你應該設置你的斷點:

tce = new timecardEntry(currentRecord.data); 

它好像它成功構建timecardEntry,不知怎的,是不是一個適當的記錄。捅一下構建可能會有所幫助。

如果不是清楚它戳這樣,爲什麼它是由壺嘴,嘗試做這樣的,像@timdev提示:

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

(你應該能夠調用grid.store.add(tce)而不是insert作爲你在最後插入。)

1

真的寫得很好的問題。好一點相關的代碼,以及你卡在什麼上的很好的解釋。不幸的是,我沒有看到任何突出的東西。

你的腳本看起來基本上是正確的。你正在接近你需要的地方。

下面是一個答案,我只是打出來,然後再重讀你的問題(和代碼),並想到了一個好一點。你可能已經知道這些東西了,但是這是給其他人的。這也是相關的,因爲我沒有在你所做的相關部分看到任何錯誤,所以你可能在別的地方吹了​​它。問題是:在哪裏以及如何?

希望有人用盡量少比我會來發現明顯的問題,在此期間,這裏是我的有關如何在內線調試,爲什麼亂寫:


你讓重要的事情了,或忽略它。您提到的那條錯誤消息:Uncaught TypeError: Cannot read property 'data' of undefined - 其中是否會發生?它看起來沒有發生在你發佈的代碼中,它可能很好地發生在ExtJS的腸子裏。

所以,觀察Firebug,並打開特徵中的「上錯誤中斷」。讓你的錯誤發生,並開始在右側(通常)查看「堆棧」窗格。該堆棧會告訴你如何到達你所在的位置。

除非我失去了一些東西(因爲我只是運行代碼在我的頭上,我很好而定),有可能是一些其他地方的配置錯誤是造成你的錯誤。

但是,與任何程序(特別是與ExtJS的,以我的經驗),調試器是你的朋友。

這樣做:

  • 使用-debug版本EXT-base.js和EXT-all.js的(直到所有的作品)
  • 使用Firebug,並
  • 「的錯誤打破」學習使用調試器來遍歷代碼,並觀察您正在操作的數據。
  • 當你發現自己深入ExtJS的腸子時,不要放棄。如果你嘗試,你會開始感覺到WTF正在發生,即使你不明白這一切,它會開始給你提示你搞砸了什麼。
+0

@timdev,謝謝你的回答。下面是導致它崩潰的確切行:grid.store.insert(newRow,recordClone);我已經從這件事情中fire the了出來,唯一我學到的就是錯誤發生在extJS的深處。 – 2010-11-27 13:50:48