Повторная вставка записи в extJS Store - PullRequest
9 голосов
/ 27 ноября 2010

Код

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' устанавливается на текущую дату и время, и он снова вставляется в хранилище как новая запись

Текущий результат

Iполучить следующую ошибку JS: Uncaught TypeError: Невозможно прочитать свойство 'data' из неопределенного

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

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

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

Спасибо.

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

Ответы [ 2 ]

3 голосов
/ 29 ноября 2010

Похоже, он неправильно строит объект tce.В этой строке вы должны установить свою точку останова:

 tce = new timecardEntry(currentRecord.data);

Кажется, что она успешно создает timecardEntry, который как-то не является надлежащей записью.Выяснить, что это за конструирование, может помочь.:

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 голос
/ 27 ноября 2010

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

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

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

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


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

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

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

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

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

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