为什么我需要在工厂使用angular.copy?

Ada*_*ner 5 javascript angularjs

我正在尝试让Thing工厂发出HTTP请求,并能够在我的控制器中使用响应.

  1. 在我的工厂,我必须这样做angular.copy(data, arr).简单地做arr = data就行不通.为什么是这样?angular.copy()只是a)删除所有内容arr和b)迭代data并分配内容arr.唯一的区别arr = dataarr指向data而不是新副本data.这为什么重要?为什么不起作用arr = data.slice(0)(根据我的理解,它几乎一样angular.copy)

  2. 实现目标的最佳方法是什么?(正确使用工厂)

main.html中

<div class="container">

<div class="page-header">
  <h1>Test App</h1>
</div>

<ul>
  <li ng-repeat="thing in things">{{thing.name}}</li>
</ul>

</div>
Run Code Online (Sandbox Code Playgroud)

main.controller.js

'use strict';

angular.module('testApp')
  .factory('Thing', function($http) {
    var arr = [];
    return {
      things: arr,
      get: function() {
        $http.get('/api/things').success(function(data) {
          angular.copy(data, arr); // this works
          // arr = data; but this doesn't
          // arr = data.slice(0); and neither does this

        });
      }
    };
  })
  .controller('MainCtrl', function ($scope, Thing) {
    Thing.get();
    $scope.things = Thing.things;
  });
Run Code Online (Sandbox Code Playgroud)

flo*_*bon 7

你的问题与角度有关,但与Javascript无关.

var arr = [] // arr is a pointer to an empty array
var things = arr  // things is a pointer to the same empty array
arr = data   // now arr points to data, but things still points to the empty array
Run Code Online (Sandbox Code Playgroud)

您可以通过运行以下代码来说服自己:

var a = [1];
var b = a;
a = [2];
// Now if you console.log a and b, a === [2] and b === [1]
Run Code Online (Sandbox Code Playgroud)

但是,如果您操纵对象的属性

var a = { data: 1 }
var b = a;
a.data = 2;
// Now a.data and b.data are the same: 2
a = { data: 3 };
// Here we changed a, not its property, so a and b are not the same anymore
// a.data === 3 but b.data === 2
Run Code Online (Sandbox Code Playgroud)

如果您了解这一点,有很多方法可以解决您的问题,例如:

angular.module('testApp')
  .factory('Thing', function($http) {
  var obj = {};
  return {
    things: obj,
    get: function() {
      $http.get('/api/things').success(function(data) {
        obj.data = data;
      });
    }
  };
})
Run Code Online (Sandbox Code Playgroud)

并在您的HTML使用things.data.

或者,如果您不想使用对象属性,而是直接使用数组,而不是替换指针,则只需更新数组的内容(因此arr仍然指向同一个数组):

angular.module('testApp')
  .factory('Thing', function($http) {
  var arr= [];
  return {
    things: arr,
    get: function() {
      $http.get('/api/things').success(function(data) {
        for (var i in data) {
          arr[i] = data[i];
        }
      });
    }
  };
})
Run Code Online (Sandbox Code Playgroud)