AngularJS 对象应该独立工作

AngularJS objects should work independently

我有 2 个数组对象都用 $http 响应初始化,但是当我尝试在一个数组中添加(推送)时,它被添加到两个数组中。

我尝试了以下代码:

控制器:

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 = "";
    }
});

Service: -- 从服务器获取数据

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 还有。

问题

$scope.objectiveData$scope.doneData 都引用同一个变量 success,所以如果你改变一个,另一个也会改变。

解决方案

通过获取success的独立副本,使$scope.objectiveData$scope.doneData引用独立变量。你可以用这个

普通 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

基本上问题是 objectiveData & doneData $scope 变量持有相同的内存位置。因此,更改任何值都会更改所有三个值 successobjectiveDatadoneData.

所以基本上你应该确保在为一个变量分配多个值时,创建该 success 变量的克隆并保留然后将该变量分配给所需的变量。

在 angularjs 中存在 angular.copy 方法,这将帮助您创建具有新内存位置的对象的克隆。这将确保新变量将指向不同的内存位置。

控制器:

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

奖励: 显然你的服务实现有误,你明确地创建了一个承诺,这就是你必须在里面调用 $digest 的原因您的 .then 成功回调。这意味着您正在创建一个案例,您必须手动 运行 摘要循环,因为代码将 运行 宁在 angularjs 上下文之外。相反,您应该 return 现有的 $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);
    });
  }
});