简体   繁体   English

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

[英]Why do I need to use angular.copy in my factory?

I'm trying to have the Thing factory make an HTTP request and be able to use the response in my controller. 我正在尝试让Thing工厂发出HTTP请求,并能够在我的控制器中使用响应。

  1. In my factory I have to do angular.copy(data, arr) . 在我的工厂,我必须做angular.copy(data, arr) Simply doing arr = data doesn't work. 简单地做arr = data不起作用。 Why is this? 为什么是这样? angular.copy() just a) deletes everything from arr and b) iterates through data and assigns stuff to arr . angular.copy()只是a)从arr删除所有内容,b)遍历data并将内容分配给arr The only difference between that and arr = data is that arr points to data rather than a new copy of data . 这与arr = data之间的唯一区别是arr指向data而不是新的data副本。 Why would this matter? 这为什么重要? And why doesn't arr = data.slice(0) work (from what I understand, it's pretty much the same as angular.copy) ? 为什么不arr = data.slice(0)工作(根据我的理解,它与angular.copy)几乎相同angular.copy)

  2. What is the best way to accomplish my goal? 实现目标的最佳方法是什么? (use the factory properly) (正确使用工厂)

main.html 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>

main.controller.js 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;
  });

Your problem is not related to angular, but to Javascript. 你的问题与角度有关,但与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

You can convince yourself of that by running the following code: 您可以通过运行以下代码来说服自己:

var a = [1];
var b = a;
a = [2];
// Now if you console.log a and b, a === [2] and b === [1]

However if you manipulate the property of an object 但是,如果您操纵对象的属性

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

If you understand that, there are many ways to solve your issue, such as: 如果您了解这一点,有很多方法可以解决您的问题,例如:

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

And in your HTML use things.data . 在你的HTML中使用things.data

Or if you don't want to use an object property, but directly the array, instead of replacing the pointer you need to only update the content of the array (so arr still points to that same array): 或者,如果您不想使用对象属性,而是直接使用数组,而不是替换指针,则只需更新数组的内容(因此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];
        }
      });
    }
  };
})

This happens because you set arr to some new instance of an array instead of using the current one. 发生这种情况是因为您将arr设置为某个新的数组实例而不是使用当前实例。 Here is an analogy to what you're doing: 这是你正在做的事情的类比:

var foo = function() {
    this.test = 'hello';
    console.log(this.test);
};

foo = function() {
    this.test = 'other';
    console.log(this.test);
};

console.log(foo()); // outputs other

angular.copy instead does something like this: angular.copy改为做这样的事情:

// foreach item in the source (in this case data)
arr.push({
   my: "value"
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM