奇怪的jQuery数据()问题-帮助


Weird jQuery data() issue - Help?

jquery 1.6.2/Firefox 6.0.1

OK,我正在处理这个发货管理器界面,当页面加载时,每个表行tr被分配一个id"shipment_XXXXX",其中XXXXX是来自数据库的发货的id。

关于发货的所有数据,在PHP中设置为一个多维关联数组,其中包含"shipmentItems"answers"pkgs"以及其他不相关的内容。shipmentItems对象是一个常规的数值数组,其中每个元素都有几个关联值,如"name"、"qty"、"price",例如:

$shipmentItems[0]["name"] = "item 1";
$shipmentItems[0]["qty"] = 5;
$shipmentItems[0]["price"] = 20.00;
$shipmentItems[1]["name"] = "item 2";
$shipmentItems[1]["qty"] = 3;
$shipmentItems[1]["price"] = 5.00;

此数组表示作为此批货的一部分的所有项目。

另一个数组pkgs是发货中每个包裹的列表,每个包裹都有一个packing_slip对象/关联数组。例子:

PACKAGE #1
$pkgs[0]['packing_slip'][0]['name'] = "item 1";
$pkgs[0]['packing_slip'][0]['qty'] = 3;
$pkgs[0]['packing_slip'][0]['price'] = 20.00;
$pkgs[0]['packing_slip'][1]['name'] = "item 2";
$pkgs[0]['packing_slip'][1]['qty'] = 1;
$pkgs[0]['packing_slip'][1]['price'] = 50.00;
PACKAGE #2
$pkgs[1]['packing_slip'][0]['name'] = "item 1";
$pkgs[1]['packing_slip'][0]['qty'] = 2;
$pkgs[1]['packing_slip'][0]['price'] = 20.00;
$pkgs[1]['packing_slip'][1]['name'] = "item 2";
$pkgs[1]['packing_slip'][1]['qty'] = 2;
$pkgs[1]['packing_slip'][1]['price'] = 50.00;

您将看到pkg数组包含每个包裹的每个装箱单的完整装运项目列表。如果您将两个包裹的0索引数量相加,您将看到它加起来等于该项目行的全部装运数量。

php将这组数据转换为JSON字符串,并将其放入相应行的隐藏表单元素中。

加载页面后,jquery遍历每个隐藏的json元素,将json字符串解析为一个对象,并将该对象附加到TR.data('shipmentItems')和TR.data('pkgs')。

这是事情变得时髦的地方…

我正在做一个函数,用户可以在其中添加一个新包裹到发货中。当他们这样做时,系统会提示他们指定哪个包裹在整批货物中每种物品的数量。他们实际上是在摆放装箱单。

它们在绘制出数量后执行的函数,从rows .data('pkgs')容器中动态地重新创建pkgs数组(对象),然后将pkgs对象重新连接回data('pkgs')容器。

我已经记录了这个函数的大量输出,数量都被分配到适当的值,见这里:

var shipmentItems = $('#shipment_'+shipid).data('shipmentItems');
var pkgs = $('#shipment_'+shipid).data('pkgs');
var pkgnum = pkgs.length; // always returns one higher than last index.
// add new pkg to array
pkgs[pkgnum] = new Object();
pkgs[pkgnum].weight = weight;
console.log("("+pkgnum+") pkgs length: " + pkgs.length);
// overwrite packing slip data.
for(var x = 0; x < pkgs.length; x++) {
    var curPS = new Array();
    var curins = 0;
    for(var y = 0; y < shipmentItems.length; y++) {
        var curqty = parseInt($('#pkgqty-'+y+'-'+x).val());
        curins += curqty * shipmentItems[y]['price'];
        curPS.push(shipmentItems[y]);
        console.log("["+y+"] before: " + curPS[y]['qty']);
        curPS[y]['qty'] = curqty;
        console.log("["+y+"] after: " + curPS[y]['qty']);
    }
    console.log(curPS[0]['qty'] + ' - ' + curPS[1]['qty']);
    pkgs[x].packing_slip = curPS;
    pkgs[x].insurance = curins;
}
// write pkgs data()
$('#shipment_'+shipid).removeData('pkgs');
$('#shipment_'+shipid).data('pkgs', pkgs);

以上日志输出如下:

(1) pkgs length: 2
[0] before: 3
[0] after: 2
[1] before: 4
[1] after: 3
2 - 3 // value of curPS[0]['qty'] and curPS[1]['qty'] for pkg#1 - pkgs[0] is set to curPS at this point.
[0] before: 2
[0] after: 1
[1] before: 3
[1] after: 1
1 - 1 // value of curPS[0]['qty'] and curPS[1]['qty'] for pkg#2 - pkgs[1] is set to curPS at this point.

这看起来很有效,对吧?错了。函数完成后,我可以按下一个按钮,输出一行的所有data()变量。不仅每一件pkg['packing_slip'][x]的数量值被设置为1,而且如果我查看同一对象日志中的shipmentItems,所有shipmentItems的数量值也被重置为1。这很奇怪,因为在代码中的任何一点都不会覆盖shipmentItems,并且应该仍然与页面加载时完全相同…

有谁知道这是怎么回事吗?

可能是因为您通过引用传递了shipmentItems - curPS.push(shipmentItems[y]);尝试通过Value - curPS.push(shipmentItems[y].slice());

好吧,多亏了你(Alon)的建议给我指明了正确的方向。slice()方法不能完全工作,因为我正在切片的数组元素包含对象,因此更深的对象仍然作为引用传递,而不是被复制。经过一番搜索,我发现jQuery.extend()方法就是复制对象数组所需要的!再次感谢!