AngularJS объекты должны работать независимо - PullRequest
0 голосов
/ 10 октября 2018

У меня есть 2 объекта массива, оба инициализированы с ответом $ http, но когда я пытаюсь добавить (push) в один массив, он добавляется в оба.

Я попробовал следующий код:

Контроллер:

myApp.controller("abc", function($scope, lastday_data){
    $scope.objectiveData = [];
    $scope.doneData = [];

    // call service & get data from server
    lastday_data.getData().then(function(success){
        $scope.objectiveData = success;
        $scope.doneData = success;
        $scope.$digest();  // *---> $digest() used*
    },function(error){
        $scope.objectiveData = null;
        $scope.doneData = null;
    });

    // add task done
    $scope.addTaskDone = function() {
        var p = {"id": 101, "name": "testadd", "check": true};
        $scope.doneData.push(p);
        $scope.textDone = "";
    }
});

Служба: - получить данные с сервера

myApp.service("lastday_data", function($http){
    this.getData = function() {
        return new Promise(function(resolve, reject){
            $http({
                method: 'GET',
                url: 'http://localhost/task/index.php/v1/example/users'
            }).then(function (response) {
                if(response.status)
                    resolve(response.data);
                else
                    reject();
            },function (error) {
                reject();
            });
        });
    }
});

Проблема: приЯ пытаюсь вызвать метод контроллера addTaskDone(), этот метод добавляет один объект в массив doneData, но этот объект также добавляется в objectiveData.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

В основном проблема заключается в том, что переменные области видимости objectiveData & doneData $ содержат одно и то же место в памяти.Таким образом, изменение любого значения приведет к изменениям во всех трех значениях success, objectiveData и doneData.

Таким образом, вы должны убедиться, что при назначении одной переменной с несколькими значениями создайтеклон этой переменной success и сохраните, а затем присвойте эту переменную требуемой переменной.

В angularjs существует метод angular.copy, который поможет вам создать клон объекта с новой ячейкой памяти.Это гарантирует, что новая переменная будет указывать на другое место в памяти.

Контроллер:

$scope.objectiveData = angular.copy(success);
$scope.doneData = angular.copy(success);

Бонус: Очевидно, что у вас неправильная реализация службы, в которой вы создаетеявное обещание - вот причина, по которой вам пришлось звонить $digest в вашем .then обратном вызове успеха.Это означает, что вы создаете случаи, когда вам нужно запустить цикл дайджеста вручную, так как код будет выполняться вне контекста angularjs.Скорее вы должны вернуть существующее $http обещание, как показано ниже, и удалить $scope.$digest() из своего кода, который вообще не нужен.

Служба

myApp.service("lastday_data", function($http) {
  this.getData = function() {
    return $http({
      method: 'GET',
      url: 'http://localhost/task/index.php/v1/example/users'
    }).then(function(response) {
      if (response.status)
        return response.data;
      else
        return $q.reject('Problem retrieving data');
    }, function(error) {
      return $q.reject(error);
    });
  }
});
0 голосов
/ 10 октября 2018

Проблема

Обе $scope.objectiveData и $scope.doneData ссылаются на одну и ту же переменную success, поэтому если вы измените одну, другая тоже изменится.

Решение

Сделайте $scope.objectiveData и $scope.doneData ссылками на независимые переменные, получив независимые копии success.Вы можете использовать для этого

Простой JavaScript

Встроенные функции AngularJS

Другие трюки

$scope.doneData = JSON.parse(JSON.stringify(success));

То есть вместо

$scope.objectiveData = success;
$scope.doneData = success;

Do (или любой другой из предыдущих вариантов)

$scope.objectiveData = success.slice(); // get a copy of success
$scope.doneData = success.slice(); // get a copy of success
...