更改服务返回的数据也会更改服务中的数据

时间:2015-10-29 21:07:25

标签: javascript angularjs angularjs-service

当我将从服务返回的数据存储在我的控制器中然后进行编辑时,它也会更改服务中的数据。

JSFiddle Demo

 /* 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);

}

这用于降价编辑器。我想将服务中的数据加载到控制器中,然后进行编辑,并在按下“保存”按钮时为服务提供新版本。 如果上述行为在Angular的数据绑定意义上是正确的,那么实现我想要的更好的解决方案是什么?

更新

根据PSL的评论和Thibaud Sowa's answer,我更改了getData()功能,以使用angular.copy()返回副本。但是,似乎无法从数组中复制一个对象(如angular.copy(arr[0])),因为它仍将返回整个数组。请参阅updated JSFiddle

更新2

嗯,我傻了。我更正了它in the fiddle。谢谢你的回答。

2 个答案:

答案 0 :(得分:0)

这是因为你要返回一个对象。在javascript中,当你这样做时,如果你传递一个指针就好了。

您应该使用angular.copy按字段复制对象字段,如下所示:

        return angular.copy(data);

请参阅此处的文档https://docs.angularjs.org/api/ng/function/angular.copy

回复您的更新

好吧,我编辑了你的小提琴,告诉你可以复制一个数组的项目。实际上,似乎所有事情都像你想要的那样......(或者我并不了解你的需要!)

更新的小提琴:

https://jsfiddle.net/thibaudsowa/aybLwa2L/3/

答案 1 :(得分:0)

您的问题有一个非常简单的解决方案:

如果您不想更改从服务中获取的数据,请复制

SO上有很多线程讨论深度复制Javascript对象的最佳方法或最优雅的方法。一个简单而快速的解决方案是使用json parse和stringify,如下所示:

var copyOfA = JSON.parse(JSON.stringify(a));

将此应用于您从服务中获得的数据,您可以去:)