Javascript 将记录重新插入extJS存储

Javascript 将记录重新插入extJS存储,javascript,json,extjs,Javascript,Json,Extjs,代码 Ext.onReady( function() { Ext.QuickTips.init(); Ext.namespace('TimeTracker'); TimeTracker.dataStore = new Ext.data.JsonStore( { root: 'timecardEntries', url: 'php/scripts/t

代码

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错误:UncaughtTypeError:无法读取未定义的属性“data”

我的问题

首先,我甚至不确定是否正确地获取了当前选定行的数据记录。其次,我不知道我收到的错误消息是什么意思

一如既往,我们非常感谢您的帮助

谢谢

更新1

经过一些调整后,我想到了以下内容(复制按钮处理程序的修改代码)

以下是我正在做的:

  • 停止编辑网格
  • 获取存储中当前的记录数
  • 抓取当前选定的记录并将其存储在内存中
  • 从存储中获取记录类型
  • 创建存储记录类型的新实例,并从所选记录传入数据对象。如果手动创建新记录,则数据对象与对象文字等效(有关详细信息,请参阅我的原始“添加按钮”代码)
  • 将创建的新对象的开始时间值更改为今天的日期和时间
  • 将记录插入网格
  • 快乐时光 请评论这段代码,并让我知道是否有更好的方法来做到这一点。谢谢

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

    我更新了代码以使用copy和add方法,它确实有效。但是,当我调用add()方法时,我会得到一个“e is undefined error”,但是当我刷新页面时,尽管出现了错误消息,记录还是被插入了。想法?

    写得很好的问题。很好的相关代码,并且很好地解释了您的问题。不幸的是,我没有看到任何突出的东西

    您的脚本看起来基本正确。你就快到你该去的地方了

    下面是我刚刚打印出来的答案,然后重新阅读您的问题(和代码),并稍微考虑一下。你可能已经知道这件事了,但它是为其他人准备的。这也是相关的,因为我看不到你所做的相关部分有任何错误,所以你可能在其他地方搞砸了。问题是:在哪里,如何

    希望没有我那么疲惫的人会出现,并发现明显的问题,同时,这里是我的涂鸦,关于如何在Ext中调试以及为什么:


    你遗漏了一些重要的事情,或者忽略了它。您提到的错误消息:
    uncaughttypeerror:无法读取未定义的属性“数据”
    --在哪里发生?看起来这并没有发生在你发布的代码中,很可能发生在ExtJS的内部

    因此,启动FireBug,并打开“出错时中断”功能。让您的错误发生,然后开始查看右侧的“堆栈”窗格(通常)。堆栈将显示您是如何到达当前位置的

    除非我遗漏了什么(因为我只是在头脑中运行你的代码,我很可能是),否则可能是其他地方的错误配置导致了你的bug

    但与任何程序一样(以我的经验,尤其是ExtJS),调试器是您的朋友

    这样做:

    • 使用ext-base.js和ext-all.js的
      -debug
      版本(直到一切正常)
    • 使用firebug和“错误时中断”
    • 学习使用调试器单步执行代码,并观察正在操作的数据
    • 当你发现自己深陷ExtJS的泥潭时,不要放弃。如果你尝试,你会开始感觉到WTF正在进行,即使你不完全理解它,它也会开始提示你哪里搞砸了

    在我看来,它没有正确构造
    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

    您能提供一些php脚本中的示例数据吗?@timdev,谢谢您的回答。下面是导致它崩溃的确切代码行:grid.store.insert(newRow,recordClone);我已经对这件事进行了彻底的Firebug测试,我学到的唯一一件事是错误发生在extJS的深处。这可能是因为你没有正确地克隆你的记录。尝试更改
    recordClone=grid.store.getAt(rowIndex)到此:
    recordClone=grid.store.getAt(rowIndex.copy()
    。可能后跟
    Ext.data.Record.id(recordClone)我想说的是,事实上,你没有克隆记录。@timdev和@Drasill,我发布了一些更新的代码。看一看。谢谢@Levi Hackith-你可能仍然有和以前一样的问题。如果在尝试将()记录插入存储区之前,尝试使用
    Ext.data.record.id(tce)
    设置该记录会怎么样?我不太清楚Record()构造函数的内部细节——我也不确定为什么不像我昨天建议的那样复制()记录——这正是copy()设计的用例。
    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);
    }