2014-11-24 101 views
4

在我的Angular應用程序中,我有一個引用多邊形座標的數組。例如:Angular.copy()不深拷貝引用數組

[[-1,0], [0,1], [1,0], [0,-1], [-1,0]]

這裏重要的一點是,在第一和最後一個點被重複,並且實際上引用相同 2長度的數組。這是我使用的插件的結果。但是,有些時候數組的創建方式會使第一個和最後一個點在具有相同值的情況下不是同一個參考。

在我的Angular應用程序的某個點上,我需要創建一個與原始座標相同的新多邊形,只需翻轉。我第一次嘗試是這樣的:

var newCoords = angular.copy(polygon.coordinates); 
for (var i = 0; i < newCoords.length; i++) { 
    newCoords[i].reverse(); 
} 

然而,那些在第一個和最後座標具有相同的情況下,我與其中一個點被逆轉兩次結束了。

我的理解是,angular.copy()創建任何傳入的深層副本,我不應該遇到此問題。顯然這是不正確的,那爲什麼?有沒有辦法去做一個真正的座標數組的深層副本,消除了奇怪的參考配對?目前我已經設法解決了這個問題,在reverse()之前增加了一個angular.copy(newCoords[i])

+0

你能重現這個問題嗎?對我而言,我正在爲我使用同樣的參考文獻,是這樣的嗎? http://jsfiddle.net/rahpuser/2ngtw4bw/2/ – rahpuser 2014-11-24 15:05:37

+0

它在我的應用程序的角度版本中必須是angular.copy()的bug。如果你看這裏(http://jsfiddle.net/2ngtw4bw/4/),按預期輸出'false true false'。當我將該代碼*完全*複製到我的應用程序中時,它會輸出'false true true'。 – 2014-11-24 16:45:46

+0

實際上,它似乎可能是Angular 1.2.1(jsfiddle)和Angular 1.2.19(我的應用程序)之間的一個bug修復*。這取決於您的深層副本的定義是否包括在新對象中維護相對引用。 angular.copy文件應該可以使這個更清晰。 – 2014-11-24 17:01:48

回答

1

正如在評論中暗示的那樣,這與角度核心內部的變化有關。此更改已在Angular v1.2.17中發佈。錯誤修復被列爲:

angular.copy:在值支撐循環引用被複制 (5c997209#7618

然而,隨着循環引用一起,雙引用也處理。要故意不處理雙引用,你有幾個選項。就像你在你的文章中提到的,在完成一個副本之後,重新複製第一個索引。不是特別直觀,但它會在任何情況下正常工作:

var newCoords = angular.copy(polygon.coordinates); 
// Ensure unique reference for the first element 
newCoords[0] = angular.copy(newCoords[0]); 

另一種選擇就是在先使用任何角度版本v1.2.17(甚至全部回v0.9.0方式),因爲它們的默認行爲是爲每個參考創建兩個不同的克隆。


對於其他人來說,可能需要做一個深層副本,但不知道確切位置,其中重複引用(甚至可能是子對象),還有另外一種方法,將與角版本一起使用前到v1.4.8。這是將第三個參數傳遞給副本以禁用循環引用處理。請注意,這將會給v1.2.17以及之前所有版本,因爲他們會簡單地忽略第三個參數,做他們的默認行爲:

var stackSource = angular.extend([], {push:angular.noop}); 
var newCoords = angular.copy(polygon.coordinates, null, noopArray); 

第三個參數是無證stackSource。通過重寫它的推動方法什麼都不做,循環參考檢測被打破。需要注意的兩件重要的事情是,循環引用將會出錯(如v1.2.16和down),並且由於性能改變,這在v1.4.8及更高版本中不起作用。在這些情況下,您將不得不編寫自己的深層複製功能。