Angularjs - расширять рекурсивный
Я хотел бы расширить некоторые рекурсивные свойства (например, глубокую копию).
очень похоже на jQuery. Я не включаю jquery только b/c из одной вещи.
jQuery.extend( true, target, object1 )
Есть ли какой-либо элегантный способ, которым вы знаете, что делает это с помощью простого javascript или angularjs?
Обновление
пожалуйста, взгляните и попытайтесь добиться того же результата
http://plnkr.co/edit/GHabYbyhsqtfBPtplksO?p=preview
Я просмотрел .copy(), но "свойства (для объектов) удалены"
Ответы
Ответ 1
Вот функция extendDeep, основанная на функции angular.extend. Если вы добавите это значение в область $, вы сможете вызвать
$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)
.
Ответ 2
Все ответы здесь действительны для версий Angular до 1.4
Как и в случае с Angular 1.4, вы можете использовать angular.merge
, чтобы выполнить именно это:
В отличие от extend(), merge() рекурсивно спускается в свойства объекта исходных объектов, выполняя глубокую копию.
https://docs.angularjs.org/api/ng/function/angular.merge
Ответ 3
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
Ответ 4
Создавая код 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;
};
Ответ 5
То же решение, что и Ryan, но с поддержкой объединения массива
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;
}
Ответ 6
Angular имеет метод копирования:
angular.copy