将记录重新插入extJS商店

时间:2010-11-27 02:44:32

标签: javascript json 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');
                                       }
                                   }
                                ]
                            }
                        ]
                    }
                )
            }
        );
    }
);

目标

当用户点击'复制'按钮,即存储记录存储在内存中,其“开始时间”按钮设置为当前日期和时间,并将其作为新记录重新插入商店

当前结果

我收到以下JS错误: Uncaught TypeError:无法读取属性'数据'未定义的

我的问题

首先,我甚至不确定我是否正确抓取当前所选行的数据记录。其次,我不知道我得到的错误信息是什么意思。

任何帮助一如既往地受到高度赞赏。

感谢。

更新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. 快乐的时光!
  9. 请批评此代码并告诉我是否有更好的方法。谢谢!

    更新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()方法时,我得到一个未定义的错误'但是当我刷新页面时,尽管出现错误消息,仍会插入记录。想法?

2 个答案:

答案 0 :(得分: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 :(得分:1)

写得很好的问题。好的相关代码,以及对你所坚持的很好的解释。不幸的是,我没有看到任何突出的东西。

你的脚本看起来大概是对的。你离你需要的地方很近。

下面是我刚输入的答案,然后重新阅读您的问题(和代码),并考虑好一点。你可能已经知道这些东西了,但是其他人都在这里。它也是相关的,因为我没有看到你所做的相关部分有任何错误,所以你可能会把它吹到其他地方。问题是:在哪里以及如何?

希望有些人比我更疲惫,会发现明显的问题,与此同时,这里是关于如何在Ext中进行调试的潦草和为什么:


你留下了重要的东西,或忽略了它。您提到的错误消息:Uncaught TypeError: Cannot read property 'data' of undefined - 哪里正在发生这种情况?看起来它并没有发布在你发布的代码中,它可能很好地发生在ExtJS的内容中。

因此,启动FireBug,并打开“出错时出错”功能。让您的错误发生,并开始查看右侧(通常)的“堆栈”窗格。堆栈将告诉你如何到达你的位置。

除非我遗漏了某些东西(因为我只是在脑海中运行你的代码,我很可能会这样做),其他地方可能存在错误配置导致你的错误。

但是就像任何程序一样(特别是使用ExtJS,根据我的经验),调试器是你的朋友。

这样做:

  • 使用-debug版本的ext-base.js和ext-all.js(直到一切正常)
  • 使用萤火虫,“打破错误”
  • 学习使用调试器逐步执行代码,并观察您正在操作的数据。
  • 当你发现自己深陷ExtJS的内心时,不要放弃。如果你尝试,你会开始意识到WTF正在发生,即使你不理解它,它也会开始给你提示你搞砸了。