2013-03-09 79 views
22

我想擴展一些屬性遞歸(又名。深度複製)。 很像jQuery所做的。我不包括jQuery只有一件事的B/C。angularjs - 擴展遞歸

jQuery.extend(true, target, object1) 

是否有任何優雅的方式,你知道它與簡單的JavaScript或angularjs?

更新 請看看,並嘗試來完成相同的結果 http://plnkr.co/edit/GHabYbyhsqtfBPtplksO?p=preview

我沒有考慮.copy(),但「屬性(對象)都將被刪除」

+1

但是你可以簡單地從jQuery的源複製'$ .extend'?這是[不難發現](https://github.com/jquery/jquery/blob/59232825aa87b941dd2418a6860b64017dfec0ae/src/core.js#L125),以及相當獨立。 – Bergi 2014-12-17 20:54:26

回答

28

這裏是基於離angular.extend功能的extendDeep功能。如果您添加到您的$範圍,那麼您需要能夠調用

$scope.meta = $scope.extendDeep(ajaxResponse1.myMeta, ajaxResponse2.defaultMeta); 

,讓你正在尋找的答案。

$scope.extendDeep = function extendDeep(dst) { 
    angular.forEach(arguments, function(obj) { 
    if (obj !== dst) { 
     angular.forEach(obj, function(value, key) { 
     if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { 
      extendDeep(dst[key], value); 
     } else { 
      dst[key] = value; 
     }  
     }); 
    } 
    }); 
    return dst; 
}; 

注意:此函數具有將來自後面參數的值複製到先前參數中的副作用。爲了簡單修復這種副作用,您可以將dst[key] = value更改爲dst[key] = angular.copy(value)

+1

這也是一個很好的解決方案,至少有角度的團隊做了類似第一個參數boolen(像jquery) – Endless 2013-03-09 14:48:23

+0

我會把它放在一些全局函數,而不是認爲... – Endless 2013-03-09 14:49:11

+0

同意。我也想,只是想演示一個簡單的方法來使用角度的方法來做到這一點。 – 2013-03-09 14:50:26

-1

角有複製方法:

angular.copy

+1

此解決方案刪除目標的內容。 angular.copy的用途與角度不同。擴展 – 2013-10-08 18:14:59

+1

-1'copy()'與'extend()'很不相同 – 2013-11-20 23:40:07

+1

絕對不是這個問題的正確答案,但是......這個答案幫助我指出了我的特定情況的正確方向。 :) – 2014-07-01 23:19:24

7
function deepExtend(destination, source) { 
    for (var property in source) { 
    if (source[property] && source[property].constructor && 
    source[property].constructor === Object) { 
     destination[property] = destination[property] || {}; 
     arguments.callee(destination[property], source[property]); 
    } else { 
     destination[property] = source[property]; 
    } 
    } 
    return destination; 
} 

Plunker

的Src:https://gist.github.com/gregdangelo/2343158

+1

這個答案只支持2個參數。 Ryan的支持多個參數,比如jQuery.extend,但一定要使用Bennett MeElwee的建議。 – user553086 2014-01-19 06:21:24

+0

arguments.callee的使用現在不鼓勵--https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee – chrismarx 2014-04-18 18:26:25

1

建立在Ryan的代碼上,你可以縮短對象檢查,你也不應該擴展函數,所以你不會覆蓋對象指針。

var extendDeep = function extendDeep(dst) { 
    angular.forEach(arguments, function(obj) { 
     if (obj !== dst) { 
      angular.forEach(obj, function(value, key) { 
       if (dst[key] && angular.isObject(dst[key])) { 
        extendDeep(dst[key], value); 
       } else if(!angular.isFunction(dst[key])) { 
        dst[key] = value; 
       } 
      }); 
     } 
    }); 
    return dst; 
}; 
0

同樣的解決方案瑞安但與陣列支持合併

function extendDeep(dst) { 
     angular.forEach(arguments, function (obj) { 
      if (obj !== dst) { 
      angular.forEach(obj, function (value, key) { 
       if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { 
        extendDeep(dst[key], value); 
       } else if (dst[key] && dst[key].constructor && dst[key].constructor === Array) { 
        dst[key].concat(value); 
       } else if(!angular.isFunction(dst[key])) { 
        dst[key] = value; 
       } 
       } 
      ); 
      } 
     } 
    ); 
     return dst; 
    }