0

Я начинаю свое Угловое контроллер при загрузке данных в формате JSON с помощью Promises и хранить его в переменных:AngularJS - это переменные перекрестные связи?

app.controller('mainController', ['$scope', '$http', '$q', function($scope, $http, $q) { 
    var req1 = $http({method: 'GET', url: 'link to JSON 1', cache: 'true'}); 
    var req2 = $http({method: 'GET', url: 'link to JSON 2', cache: 'true'}); 

    $q.all([req1, req2]).then(function(response){ 
    var res1 = response[0].data; 
    var res2 = response[1].data; 

    $scope.data1 = res1;  // JSON which I will manipulate 
    $scope.data1Ref = res1; // JSON for reference which I won't manipulate 

    $scope.data2 = res2; 
    $scope.data2Ref = res2; 

    init(); // do the stuff with the data 
    }); 
}]); 

После init() делается, однако, если я проверю $scope.data1 и $scope.data1Ref оба они были изменены, то есть они обязаны вместе.

Почему это происходит и как я могу хранить сохраненную версию оригинального загруженного JSON для справки?

+0

Это потому, что $ scope.data1 и $ scope.data1Ref ссылка res1, поэтому любые изменения res1 будут отражены в этих двух. Перед назначением вам нужно сделать копию res1. –

+0

http://stackoverflow.com/questions/29749433/difference-between-angular-copy-and-assignment – dhemz

ответ

0

Это потому, что в JavaScript объекты передаются по ссылке. Когда вы устанавливаете $ scope.data1 и $ scope.data1Ref равным res1, вы устанавливаете их равными с ссылкой на res1.

Чтобы обойти это, вы можете сделать глубокую копию своих объектов res с помощью angular.copy.

$scope.res1Ref = angular.copy(res1);

+1

Интересно, что 'angular.copy()', кажется, занимает значительное количество времени для запуска (в этом случае почти 4000 мс) , больше, чем загрузка JSON снова. Поэтому потенциально обходной путь, по крайней мере в этом случае, будет загружать JSON дважды. – bplmp

+0

Кто-то еще с этой проблемой нашел более быстрый алгоритм клонирования: https://github.com/angular/angular.js/issues/11099 Кроме того, lodash имеет функцию глубокого клонирования, которую вы можете попробовать, _.cloneDeep() https://lodash.com/docs#cloneDeep – paulgoblin

+1

Большое спасибо за это, paulgoblin. Использование кода https://github.com/angular/angular.js/issues/11099 привело к значительному повышению производительности. – bplmp

0

Когда вы используете назначение объектов, вы предоставляете переменную только ссылку на объект, а не копирование объекта. В вашем коде $scope.data1, $scope.data1Ref и res1 все указывают на точный экземпляр объекта. Чтобы создать новый объект, вам необходимо скопировать существующий объект.

Угловой обеспечивает две функции, которые могут копировать объект, один создает мелкую копию, а другую - глубокую копию. Неглубокая копия копирует примитивные поля, и если объект содержит дочерние объекты, оригинал и копия указывают на один и тот же экземпляр дочернего объекта. В глубокой копии любые дочерние объекты также создают новые копии.

angular.extend может использоваться для создания мелкой копии, а angular.copy выполняет глубокую копию.

Смежные вопросы