2010-11-27 3 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 ошибки: неперехваченным TypeError: Не удается прочитать свойство «данные» неопределенной

Мой вопрос (ы)

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

Любая помощь, как всегда, высоко ценится.

Спасибо.

Update 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. Grab типа записи из магазина
  5. Создайте новый экземпляр типа магазина записи, и передать в объекте данных из выбранной записи. Объект данных эквивалентен литералу объекта, если вы делаете новую запись вручную (см. Мой оригинальный код кнопки «Добавить»).
  6. Изменение значения start_time нового объекта, который был создан для сегодняшней даты и времени
  7. Внести рекорд в сетку
  8. С праздником!

Прошу прокомментировать этот код и сообщить мне, если есть лучший способ сделать это. Благодаря!

Update 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 is undefined error», но когда я обновляю страницу, запись вставлена, несмотря на сообщение об ошибке. Идеи?

+0

Можете ли вы предоставить некоторые примеры данных из сценария php? – rwilliams 2010-11-27 04:07:29

ответ

3

Похоже, что он не строит объект tce правильно. Эта линия, где вы должны установить точки останова:

tce = new timecardEntry(currentRecord.data); 

Похоже, он успешно строит timecardEntry что-то не является собственно запись. Имея подсунуть только то, что это is Строительство может помочь.

Если это не видно из тыкать на это так, почему это до носика, попробуйте сделать это так, как предполагает @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

Действительно хорошо написанный вопрос. Хороший бит соответствующего кода, и хорошее объяснение того, что вы застряли. К сожалению, я не вижу ничего, что выделяется.

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

Ниже приведен ответ, который я только что напечатал, а затем перечитал ваш вопрос (и код) и подумал немного лучше. Вы, наверное, уже знаете это, но он здесь для кого-то еще. Это также актуально, потому что я не вижу ошибок в соответствующей части того, что вы сделали, поэтому вы, вероятно, взорвали его где-то в другом месте. Вопросы: где и как?

Надеется, кто-то менее истощены, чем я придет и найти очевидную проблему, в то же время, вот мои каракули о том, как отлаживать в Ext и почему:


Вы оставили что-то важное из , или не обратил на это внимания. Это сообщение об ошибке, которое вы упомянули: Uncaught TypeError: Cannot read property 'data' of undefined - , где, что происходит? Похоже, что это не происходит в коде, который вы опубликовали, это вполне может произойти в недрах ExtJS.

Итак, запустите FireBug и включите функцию «break on error». Сделайте свою ошибку и начните смотреть на панель «Стек» справа (обычно). Стек покажет вам, как вы добрались до своего места.

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

Но как и любая программа (и особенно с ExtJS, по моему опыту), отладчик - ваш друг.

Сделайте это:

  • Используйте версию -debug из Ext-base.js и доб-all.js (пока он все работы)
  • Использование поджигатель, и "разбить на ошибки"
  • Научитесь использовать отладчик для перехода по коду и для просмотра данных, на которых вы работаете.
  • Не сдавайтесь, когда вы оказываетесь глубоко в недрах ExtJS. Если вы попробуете, вы начнете понимать, что WTF продолжается, и даже если вы не понимаете все это, он начнет давать вам подсказки о том, где вы напортачили.
+0

@timdev, спасибо за ответ. Вот точная строка, которая вызывает ее сбой: grid.store.insert (newRow, recordClone); Я черпаю чертовски из этого, и единственное, что я узнал, это то, что ошибка происходит глубоко внутри extJS. – 2010-11-27 13:50:48

Смежные вопросы