2015-02-07 83 views
5

我試圖讓Thing工廠發出HTTP請求,並能夠在我的控制器中使用響應。爲什麼我需要在我的工廠使用angular.copy?

  1. 在我的工廠我必須做angular.copy(data, arr)。只是做arr = data不起作用。爲什麼是這樣? angular.copy()只是a)刪除arr中的所有內容,b)通過data進行迭代並將內容分配給arr。與arr = data唯一的區別是arr指向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> 

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; 
    }); 
+0

angular.copy適用於對象或數組,數據是一個對象嗎?順便說一句,你應該利用提升和提取你的匿名函數到命名函數中,並簡單地將函數名稱傳遞給工廠和控制器方法。使得更容易找出模塊的組件。 – Robert 2015-02-07 05:35:59

+0

'data'是一個對象數組。 – 2015-02-07 05:41:36

+1

它可以工作,因爲arr(數組)是一個引用,並且您需要保留引用才能使範圍綁定起作用。否則,你只是用一個新的引用覆蓋arr--這是與最初綁定到作用域的引用完全不同的對象。 – pixelbits 2015-02-07 05:49:14

回答

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 

您可以通過運行下面的代碼說服的是自己:

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

但是,如果你操縱的對象

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 

的財產,如果你明白,有很多如何解決你的問題,如:

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

並在您的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]; 
     } 
     }); 
    } 
    }; 
}) 
+0

啊我事後覺得很愚蠢。謝謝! – 2015-02-07 15:13:07

0

發生這種情況是因爲您將arr設置爲某個數組的新實例,而不是使用當前的實例。這裏是一個比喻,你在做什麼:

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而不是做這樣的事情:

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