这是以下链接的后续帖子。我在那里得到了帮助,显示我的代码在jsfiddle上按预期工作,所以在创建嵌套数组并将对象推送到它们时,必须有一个我不理解的概念: Updating elemint in JSON updates ALL
这个问题听起来像是确切的问题,虽然在javascript中对我来说,我有但我无法解释如何将正确答案应用于我的用例: How to avoid referencing the same index in an array (Java)?
这个订购用户界面有点不正统,他们首先选择帐户,然后当他们选择任何产品后,必须将其添加到所有帐户。
My Array是JS:
runningOrdfers = {
"id": 1402846607011,
"status": "unsaved",
"accounts": [
{
"compid": 919759,
"compname": null,
"products": [
{
"BCINUM": "539504",
"ITEMUNIT": "EA",
"ORDERDETAILS": [
{
"SHIPDATEID": "69230",
"SHIPPERIODID": "2096",
"QUANTITY": "1"
},
{
"SHIPDATEID": "69231",
"SHIPPERIODID": "2096",
"QUANTITY": "2"
}
],
"SHIPPINGCOMMENTS": ""
}
]
},
{
"compid": 920001,
"compname": null,
"products": [
{
"BCINUM": "539504",
"ITEMUNIT": "EA",
"ORDERDETAILS": [
{
"SHIPDATEID": "69230",
"SHIPPERIODID": "2096",
"QUANTITY": "1"
},
{
"SHIPDATEID": "69231",
"SHIPPERIODID": "2096",
"QUANTITY": "2"
}
],
"POTEXT": "",
"SHIPPINGCOMMENTS": ""
}
]
}
]
以下是我如何创建对象并将其追加到数组中。首先,创建一个新订单:
var runningOrders = {};
function createNewOrder(event) {
var uniqueID = uniqueIdentifier();
var accounts = [];
var products = [];
runningOrders.id = uniqueID;
runningOrders.status = "unsaved";
runningOrders["accounts"] = accounts;
runningOrders.accounts["products"] = products;
selectAccountsTab(event);
}
然后将帐户添加到订单中:
function addAccountToOrder(compID) {
getAccount(compID);
var thisAccount = {};
var n = savedAccountByCompID.length;
for (var i = 0; i < n; i++) {
var accountListObject = savedAccountByCompID[i];
thisAccount.compid = +accountListObject.COMPID;
thisAccount.compname = +accountListObject.COMPNAME;
thisAccount.products = [];
runningOrders.accounts.push(thisAccount);
}
}
最后按刚刚创建的顺序将产品添加到帐户中:
function setProductSelected(bcinum){
var thisProductSelected = {};
var thisProduct = "bcinum" + bcinum;
var thisProductData = productData[thisProduct];
thisProductSelected.BCINUM = thisProductData.BCINUM;
thisProductSelected.ITEMUNIT = thisProductData.ITEMUNIT;
thisProductSelected.ORDERDETAILS = [];
thisOrderDetails = {
SHIPDATEID: "69230",
SHIPPERIODID: "2096",
QUANTITY: ""
};
thisProductSelected.ORDERDETAILS.push(thisOrderDetails);
thisOrderDetails = {
SHIPDATEID: "69231",
SHIPPERIODID: "2096",
QUANTITY: ""
};
thisProductSelected.ORDERDETAILS.push(thisOrderDetails);
var a = runningOrders.accounts.length;
for (var ii = 0; ii < a; ii++) {
currAccount = runningOrders.accounts[ii]; //possible problem? Loping over accounts and pushing same object?
currAccount.products.push(thisProductSelected);
}
}
我的函数迭代并更新我导航到的索引的元素:
function updateComments(compID,bcinum,comment) {
var accounts = runningOrders.accounts;
var n = accounts.length;
for (i = 0; i < n; i++) {
if (accounts[i].compid == compID) {
var p = accounts[i].products.length;
for (ii = 0; ii < p; ii++) {
if (accounts[i].products[ii].BCINUM == bcinum) {
accounts[i].products[ii].SHIPPINGCOMMENTS = comment;
}
}
}
}
}
当我调用我的更新功能时,它正在更新所有索引位置的SHIPPINGCOMMENTS而不是我想要更新的位置,这是基于compID:
updateComments(919759,539504, '越早');
答案 0 :(得分:1)
无论可读性问题如何,这似乎都按照this jsbin中所示的设计工作。似乎还有其他事情要发生。
这是一个很好的例子,说明不变性如何能够带来很大帮助。围绕不可变数据结构设计代码可以减轻复杂性和与真实的混淆。遗憾的是,在JavaScript中(默认情况下)对象是通过引用而不是通过值来管理的,因此语言本身不直接支持不可变对象。较新的版本(ECMAScript 5)支持Object.freeze
,但您需要在较旧/功能失常的浏览器中使用polyfill。
为了管理深层嵌套数据结构的复杂性,它可以帮助将数据封装在自定义对象(经典面向对象设计中定义的对象,尽管在JavaScript的情况下,这将是一个原型对象)。但是,这超出了原始问题的范围(请参阅prototypical object oriented design上的此博文)。