javascript 将记录重新插入 extJS 存储
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4289850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Re-inserting a Record into an extJS Store
提问by Levi Hackwith
The code
代码
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');
}
}
]
}
]
}
)
}
);
}
);
The Goal
目标
When the user clicks the 'copy' button, that store record is stored into memory, its 'start_time' is set to the current date and time, and it is re-inserted into the store as a new record
当用户单击“复制”按钮时,该存储记录被存储到内存中,其“开始时间”设置为当前日期和时间,并作为新记录重新插入存储中
The Current Result
当前结果
I receive the following JS error: Uncaught TypeError: Cannot read property 'data' of undefined
我收到以下 JS 错误:Uncaught TypeError: Cannot read property 'data' of undefined
My Question(s)
我的问题
For starters, I'm not even sure if I'm grabbing the currently selected row's data record properly. Second, I have no idea what the error message I'm getting means.
首先,我什至不确定我是否正确抓取了当前选定行的数据记录。其次,我不知道我收到的错误消息是什么意思。
Any help is, as always, highly appreciated.
一如既往,任何帮助都受到高度赞赏。
Thanks.
谢谢。
Update 1
更新 1
After some tweaking, here's what I came up with (this modified code for the copy button handler)
经过一些调整,这就是我想出的(复制按钮处理程序的修改代码)
{
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');
}
}
]
}
Here's what I'm doing:
这是我在做什么:
- Stop editing the grid
- Get the number of records currently in the store
- Grab the currently selected record and store it in memory
- Grab the record type from the store
- Make a new instance of the store record type, and pass in the data object from the selected record. The data object is equivalent to the object literal if you were making a new record by hand (see my original 'add button' code for details)
- Alter the start_time value of the new object that was created to today's date and time
- Insert record into grid
- Happy time!
- 停止编辑网格
- 获取当前存储中的记录数
- 抓取当前选中的记录并存入内存
- 从商店中获取记录类型
- 创建一个 store 记录类型的新实例,并从所选记录中传入数据对象。如果您手动创建新记录,则数据对象等效于对象文字(有关详细信息,请参阅我原来的“添加按钮”代码)
- 将创建的新对象的 start_time 值更改为今天的日期和时间
- 将记录插入网格
- 欢乐时光!
Please critique this code and let me know if there's a better way to do it. Thanks!
请批评这段代码,让我知道是否有更好的方法来做到这一点。谢谢!
Update 2:
更新 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);
}
}
I updated the code to use the copy and add methods and it does work. However, when I call the add() method I get a 'e is undefined error' but when I refresh the page, the record is inserted despite the error message. Ideas?
我更新了代码以使用复制和添加方法,它确实有效。但是,当我调用 add() 方法时,我得到一个“e 未定义错误”,但是当我刷新页面时,尽管有错误消息,但仍会插入记录。想法?
采纳答案by wombleton
Looks to me like it's not constructing the tceobject correctly. This line is where you should set your breakpoint:
在我看来,它没有tce正确构造对象。这一行是您应该设置断点的地方:
tce = new timecardEntry(currentRecord.data);
It seems like it's successfully constructing a timecardEntrythat somehow isn't a proper record. Having a poke at just what it isconstructing may help.
似乎它正在成功构建一个timecardEntry不知何故不是正确记录的记录。看看它正在构建的东西可能会有所帮助。
If it's not apparent from poking at it that way why it's up the spout, try doing it like this, like @timdev suggests:
如果以这种方式戳它并不清楚为什么它会出现在喷口上,请尝试这样做,就像@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);
}
(You should be able to call grid.store.add(tce)instead of insertas you're inserting at the end.)
(您应该能够调用grid.store.add(tce)而不是insert在最后插入时调用。)
回答by timdev
Really well-written question. Good bit of relevant code, and nice explanation of what you're stuck on. Unfortunately, I don't see anything that stands out.
问题写得真好。很好的相关代码,以及对你所坚持的内容的很好的解释。不幸的是,我没有看到任何突出的东西。
Your script looks mostly right. You're close to being where you need to be.
您的脚本看起来基本正确。您即将到达您需要到达的地方。
Below is an answer that I just typed out, and then reread your question (and code), and thought a little better of. You probably know this stuff already, but it's here for anyone else. It's also relevant, because I don't see any errors in the relevant part of what you did, so you probably blew it somewhere else. The questions are: where and how?
下面是我刚刚输入的答案,然后重读了您的问题(和代码),然后再想一想。你可能已经知道这些东西,但它是为其他人准备的。这也是相关的,因为我在你所做的相关部分没有看到任何错误,所以你可能在其他地方吹了它。问题是:在哪里以及如何?
Hopefully someone less exhausted than i am will come along and find the obvious problem, in the meantime, here's my scrawl about how to debug in Ext and why:
希望有人比我更不累,会发现明显的问题,与此同时,这是我关于如何在 Ext 中调试以及原因的潦草:
You've left something important out, or overlooked it. That error message you mentioned: Uncaught TypeError: Cannot read property 'data' of undefined-- whereis that happening? It looks like it's not happening in the code you posted, it might very well be happening down in the bowels of ExtJS.
你遗漏了一些重要的东西,或者忽略了它。您提到的错误消息:Uncaught TypeError: Cannot read property 'data' of undefined--发生在哪里?看起来它没有发生在您发布的代码中,它很可能发生在 ExtJS 的内部。
So, fire up FireBug, and turn on the "break on error" feature. Make your error happen, and start looking at the "stack" pane over on the right (usually). The stack will show you how you got to where you are.
因此,启动 FireBug,并打开“错误时中断”功能。使您的错误发生,并开始查看右侧的“堆栈”窗格(通常)。该堆栈将向您展示如何到达您所在的位置。
Unless I'm missing something (and since I'm just running your code in my head, I very well may be), there's probably something misconfigured elsewhere that's causing your bug.
除非我遗漏了什么(并且因为我只是在脑海中运行你的代码,我很可能是),否则其他地方可能有一些错误配置导致了你的错误。
But as with any program (and especially with ExtJS, in my experience), the debugger is your friend.
但是对于任何程序(尤其是 ExtJS,根据我的经验),调试器是你的朋友。
Do this:
做这个:
- Use the
-debugversion of ext-base.js and ext-all.js (until it all works) - Use firebug, and "break on errors"
- Learn to use the debugger to step through code, and to watch the data you're operating on.
- Don't give up when you find yourself deep in the bowels of ExtJS. If you try, you'll start to get a sense of WTF is going on, and even if you don't understand it all, it will start to give you hints about where you screwed up.
- 使用
-debugext-base.js 和 ext-all.js 的版本(直到一切正常) - 使用萤火虫,并“打破错误”
- 学习使用调试器单步调试代码,并观察您正在操作的数据。
- 当您发现自己深入 ExtJS 时不要放弃。如果你尝试,你会开始感觉到 WTF 正在发生,即使你不理解这一切,它也会开始给你暗示你在哪里搞砸了。

