更改从服务返回的数据也会更改服务中的数据
Changing data returned from service changes data in service too
当我将服务返回的数据存储在我的控制器中然后对其进行编辑时,它也会更改服务中的数据。
/* The backend connection part and the actual markdown editor JS have been removed because it would just make the code huge and is irrelevant to the problem */
var myApp = angular.module('myApp', []);
// In my app, this service caches blog post data from my server on the client side and returns single posts from it
myApp.factory('PostService', function ($log, $filter, $http) {
var data;
// Just an example for data pulled from server
data = [{
id: 99999,
text: "Hello"
}];
// Function for returning a post out of the data array loaded from the server
var getData = function (id) {
if (id !== undefined) {
var arr = $filter('filter')(data, {
id: id
});
if (arr.length === 0) {
$log.error('PostService:: getData(' + id + '):: Post Not Found');
return 'not_found';
} else {
$log.debug('PostService:: getData(' + id + '):: Post returned');
return arr[0];
}
} else {
return data;
}
};
return {
getData: getData
};
});
function ctrl($log, $scope, PostService) {
var edit = this;
// Sample post id
edit.editingId = 99999;
// "Copy" (apparrently more "bind") the blog post data to edit.data
edit.data = PostService.getData(edit.editingId);
}
这用于降价编辑器。我想将服务中的数据加载到控制器中,然后对其进行编辑,并在按下 "Save" 按钮时为服务提供新版本。
如果上述行为在 Angular 的数据绑定意义上是正确的,那么什么是实现我想要的更好的解决方案?
更新
基于PSL's comment and I changed the getData()
function to return a copy using angular.copy()
. However, it seems not to be possible to copy one object out of an array (like angular.copy(arr[0])
), as it will still return the whole array. See the updated JSFiddle.
更新 2
好吧,我很笨。我更正了它 in the fiddle。谢谢你的回答。
这是因为您正在返回一个对象。在 javascript 中,当您这样做时,就像传递指针一样。
您应该使用 angular.copy 逐字段复制对象,如下所示:
return angular.copy(data);
在此处查看文档 https://docs.angularjs.org/api/ng/function/angular.copy
对您更新的回应
好吧,我编辑了你的 fiddle,向你展示了你可以复制数组的一个项目。其实好像每件事都如你所愿...(或者我没理解你的需求!)
更新后fiddle:
您的问题有一个非常简单的解决方案:
如果您不想更改从服务中获取的数据,请复制一份
SO 上有很多线程讨论深度复制 Javascript 对象的最快或最优雅的方法。一个简单而快速的解决方案是使用 json 解析和字符串化,如下所示:
var copyOfA = JSON.parse(JSON.stringify(a));
将此应用到您从服务中获得的数据,您就可以开始了:)
当我将服务返回的数据存储在我的控制器中然后对其进行编辑时,它也会更改服务中的数据。
/* The backend connection part and the actual markdown editor JS have been removed because it would just make the code huge and is irrelevant to the problem */
var myApp = angular.module('myApp', []);
// In my app, this service caches blog post data from my server on the client side and returns single posts from it
myApp.factory('PostService', function ($log, $filter, $http) {
var data;
// Just an example for data pulled from server
data = [{
id: 99999,
text: "Hello"
}];
// Function for returning a post out of the data array loaded from the server
var getData = function (id) {
if (id !== undefined) {
var arr = $filter('filter')(data, {
id: id
});
if (arr.length === 0) {
$log.error('PostService:: getData(' + id + '):: Post Not Found');
return 'not_found';
} else {
$log.debug('PostService:: getData(' + id + '):: Post returned');
return arr[0];
}
} else {
return data;
}
};
return {
getData: getData
};
});
function ctrl($log, $scope, PostService) {
var edit = this;
// Sample post id
edit.editingId = 99999;
// "Copy" (apparrently more "bind") the blog post data to edit.data
edit.data = PostService.getData(edit.editingId);
}
这用于降价编辑器。我想将服务中的数据加载到控制器中,然后对其进行编辑,并在按下 "Save" 按钮时为服务提供新版本。 如果上述行为在 Angular 的数据绑定意义上是正确的,那么什么是实现我想要的更好的解决方案?
更新
基于PSL's comment and getData()
function to return a copy using angular.copy()
. However, it seems not to be possible to copy one object out of an array (like angular.copy(arr[0])
), as it will still return the whole array. See the updated JSFiddle.
更新 2
好吧,我很笨。我更正了它 in the fiddle。谢谢你的回答。
这是因为您正在返回一个对象。在 javascript 中,当您这样做时,就像传递指针一样。
您应该使用 angular.copy 逐字段复制对象,如下所示:
return angular.copy(data);
在此处查看文档 https://docs.angularjs.org/api/ng/function/angular.copy
对您更新的回应
好吧,我编辑了你的 fiddle,向你展示了你可以复制数组的一个项目。其实好像每件事都如你所愿...(或者我没理解你的需求!)
更新后fiddle:
您的问题有一个非常简单的解决方案:
如果您不想更改从服务中获取的数据,请复制一份
SO 上有很多线程讨论深度复制 Javascript 对象的最快或最优雅的方法。一个简单而快速的解决方案是使用 json 解析和字符串化,如下所示:
var copyOfA = JSON.parse(JSON.stringify(a));
将此应用到您从服务中获得的数据,您就可以开始了:)