Подтвердить что ты не робот

Angularjs - расширять рекурсивный

Я хотел бы расширить некоторые рекурсивные свойства (например, глубокую копию). очень похоже на jQuery. Я не включаю jquery только b/c из одной вещи.

jQuery.extend( true, target, object1 )

Есть ли какой-либо элегантный способ, которым вы знаете, что делает это с помощью простого javascript или angularjs?

Обновление пожалуйста, взгляните и попытайтесь добиться того же результата http://plnkr.co/edit/GHabYbyhsqtfBPtplksO?p=preview

Я просмотрел .copy(), но "свойства (для объектов) удалены"

4b9b3361

Ответ 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