在 SAPUI5 中更改复制的数据时原始模型正在更改
Original model is changing when changing the copied data in SAPUI5
我正在通过 API 获取一些数据 (JSONArray) 并将其保存在两个模型和一个数组变量中。我正在处理数组中的数据,但它也在更改模型中的值。下面是我的一些代码片段:
onInit : function(){
this.addmodel = new sap.ui.model.json.JSONModel();
this.addmodel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.addmodel, "Model");
this.originalModel = new sap.ui.model.json.JSONModel();
this.originalModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.originalModel, "OrgModel");
this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},
Controller.js :
_handleRouteMatched: function (evt) {
if (evt.getParameter("name") !== "BookMeal") {
return;
}
$.ajax({
url: "/Non_sap_create_requests/odata/MealSelfLocMealType",
method: "GET",
dataType: "json",
success: function (data) {
that.mCopiedArray = $.extend([], data.value);
that.originalModel.setData(data);
that.addmodel.setData(data);
},
error: function (err) {
}
});
onFromDateSelect: function (oEvent) {
if (Date.parse(fromDate) === Date.parse(currentDate)) {
var tempVal = that.mCopiedArray;
tempVal = formatter.mealContsraints(tempVal, currentDate, fromDate, currentTime, "null");
that.addmodel.setProperty("/value", tempVal);
} else {
that.addmodel.setProperty("/value", that.originalModel.getProperty("/value"));
}
},
});
});
在上面的代码中,我将数据保存在数组 mCopiedArray 和 2 个模型中 - addmodel 和 originalModel。我正在处理 formatter.js 中的数据。更改 mCopiedArray 中的数据也会更改 addmodel 和 originalModel 中的数据。
formatter.js :
mealContsraints: function (value, currentDate, fromDate, currentTime, meal) {
if (fromdate === currentdate) {
while (ln--) {
if (value[ln].MealField === "Breakfast") {
value.splice(ln, 1);
break;
}
}
ln = value.length;
if (currentTime > '11:30:00') {
while (ln--) {
if (value[ln].MealField === "Lunch") {
value.splice(ln, 1);
break;
}
}
}
ln = value.length;
if (currentTime > '16:30:00') {
while (ln--) {
if (value[ln].MealField === "Eve Snacks") {
value.splice(ln, 1);
break;
}
}
}
if (currentTime > '18:00:00') {
while (ln--) {
if (value[ln].MealField === "Dinner") {
value.splice(ln, 1);
break;
}
}
}
}
对象是工作参考逻辑,因此您可以使用 jquery.extend()。
$.extend([], data.value);
不会 创建深拷贝。因此,如果您修改数组中的项目(例如,将 MealField
从 Dinner
更改为 Midnight Snack
),它也会在模型中更改。
但是如果您修改数组本身(例如从数组中删除一个项目),应该不会影响模型。
我为此做了一个小片段:
const mData = {value: [
{ MealField: "Dinner", id: 3 },
{ MealField: "Lunch", id: 2 },
{ MealField: "Breakfast", id: 1 }
]};
const oModel = new sap.ui.model.json.JSONModel(mData);
const aCopy = $.extend([], mData.value);
aCopy.splice(1, 1);
// arrays should be different
console.log(aCopy);
console.log(oModel.getProperty("/value"));
aCopy[0].MealField = "Midnight Snack";
// single item should be the same
console.log(aCopy[0]);
console.log(oModel.getProperty("/value/0"));
所以问题不应该是格式化程序,而是其他问题?
顺便说一句,您的格式化程序不是格式化程序。一个真正的格式化程序应该 return 一个值并且没有副作用(比如修改 models/data)。
制作对象深拷贝的一种方法是将其序列化为 json 并将其反序列化为新对象:
令 objString = JSON.stringfy(obj):
让 newObject = JSON.parse(objString)
PS:这将适用于可序列化的属性,如果你有
您可能 运行 遇到性能问题的巨大对象。
我正在通过 API 获取一些数据 (JSONArray) 并将其保存在两个模型和一个数组变量中。我正在处理数组中的数据,但它也在更改模型中的值。下面是我的一些代码片段:
onInit : function(){
this.addmodel = new sap.ui.model.json.JSONModel();
this.addmodel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.addmodel, "Model");
this.originalModel = new sap.ui.model.json.JSONModel();
this.originalModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.originalModel, "OrgModel");
this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},
Controller.js :
_handleRouteMatched: function (evt) {
if (evt.getParameter("name") !== "BookMeal") {
return;
}
$.ajax({
url: "/Non_sap_create_requests/odata/MealSelfLocMealType",
method: "GET",
dataType: "json",
success: function (data) {
that.mCopiedArray = $.extend([], data.value);
that.originalModel.setData(data);
that.addmodel.setData(data);
},
error: function (err) {
}
});
onFromDateSelect: function (oEvent) {
if (Date.parse(fromDate) === Date.parse(currentDate)) {
var tempVal = that.mCopiedArray;
tempVal = formatter.mealContsraints(tempVal, currentDate, fromDate, currentTime, "null");
that.addmodel.setProperty("/value", tempVal);
} else {
that.addmodel.setProperty("/value", that.originalModel.getProperty("/value"));
}
},
});
});
在上面的代码中,我将数据保存在数组 mCopiedArray 和 2 个模型中 - addmodel 和 originalModel。我正在处理 formatter.js 中的数据。更改 mCopiedArray 中的数据也会更改 addmodel 和 originalModel 中的数据。
formatter.js :
mealContsraints: function (value, currentDate, fromDate, currentTime, meal) {
if (fromdate === currentdate) {
while (ln--) {
if (value[ln].MealField === "Breakfast") {
value.splice(ln, 1);
break;
}
}
ln = value.length;
if (currentTime > '11:30:00') {
while (ln--) {
if (value[ln].MealField === "Lunch") {
value.splice(ln, 1);
break;
}
}
}
ln = value.length;
if (currentTime > '16:30:00') {
while (ln--) {
if (value[ln].MealField === "Eve Snacks") {
value.splice(ln, 1);
break;
}
}
}
if (currentTime > '18:00:00') {
while (ln--) {
if (value[ln].MealField === "Dinner") {
value.splice(ln, 1);
break;
}
}
}
}
对象是工作参考逻辑,因此您可以使用 jquery.extend()。
$.extend([], data.value);
不会 创建深拷贝。因此,如果您修改数组中的项目(例如,将 MealField
从 Dinner
更改为 Midnight Snack
),它也会在模型中更改。
但是如果您修改数组本身(例如从数组中删除一个项目),应该不会影响模型。
我为此做了一个小片段:
const mData = {value: [
{ MealField: "Dinner", id: 3 },
{ MealField: "Lunch", id: 2 },
{ MealField: "Breakfast", id: 1 }
]};
const oModel = new sap.ui.model.json.JSONModel(mData);
const aCopy = $.extend([], mData.value);
aCopy.splice(1, 1);
// arrays should be different
console.log(aCopy);
console.log(oModel.getProperty("/value"));
aCopy[0].MealField = "Midnight Snack";
// single item should be the same
console.log(aCopy[0]);
console.log(oModel.getProperty("/value/0"));
所以问题不应该是格式化程序,而是其他问题?
顺便说一句,您的格式化程序不是格式化程序。一个真正的格式化程序应该 return 一个值并且没有副作用(比如修改 models/data)。
制作对象深拷贝的一种方法是将其序列化为 json 并将其反序列化为新对象:
令 objString = JSON.stringfy(obj): 让 newObject = JSON.parse(objString)
PS:这将适用于可序列化的属性,如果你有 您可能 运行 遇到性能问题的巨大对象。