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

Глубокие объекты копирования в Angular

Угловой JS имеет angular.copy() для глубоких копий объектов и массивов.

Есть ли у Angular что-то вроде этого?

4b9b3361

Ответ 1

Вы также можете использовать:

JSON.parse(JSON.stringify(Object))

если он находится в вашей области видимости, в каждом компоненте Angular, директиве и т.д., а также в каждой среде node.

Если у вас нет циркулярной ссылки, она должна работать и эффективно отделяет вашу ссылку на исходный объект.

Ответ 2

Другой вариант - реализовать собственную функцию:

/**
 * Returns a deep copy of the object
 */
public static deepCopy(oldObj: any) {
    var newObj = oldObj;
    if (oldObj && typeof oldObj === "object") {
        if (oldObj instanceof Date) {
           return new Date(oldObj.getTime());
        }
        newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
        for (var i in oldObj) {
            newObj[i] = this.deepCopy(oldObj[i]);
        }
    }
    return newObj;
}

Ответ 3

Этот вопрос не является дубликатом Как я могу использовать angular.copy в angular 2, потому что OP спрашивает о глубоком копировании объектов. В связанном ответе рекомендуется Object.assign(), который не делает глубокую копию.

На самом деле, использование Angular2 не ограничивает вас от использования других библиотек, таких как jQuery, для глубокого копирования объектов с их функцией $.clone() или lodash с _.cloneDeep().

У наиболее распространенных библиотек есть свои типизации, доступные через инструменты CLI, поэтому даже при переносе из TypeScript вы можете легко использовать все, что захотите.

Также смотрите: Каков наиболее эффективный способ глубокого клонирования объекта в JavaScript?

Ответ 4

Вы можете deep copy объект в Angular, используя метод lodash cloneDeep:

Установить lodash с yarn add lodash или npm install lodash.

В свой компонент импортируйте cloneDeep и используйте его:

import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);

Это только 18 КБ, добавленных к вашей сборке, что хорошо для выгоды.

Я также написал статью здесь, если вам нужно больше понять, почему вы используете lodash cloneDeep.

Ответ 5

Create helper class with name deepCopy.ts

/*
* DeepCopy class helps to copy an Original Array or an Object without impacting on original data
*/

export class DeepCopy {

  static copy(data: any) {
    let node;
    if (Array.isArray(data)) {
      node = data.length > 0 ? data.slice(0) : [];
      node.forEach((e, i) => {
        if (
          (typeof e === 'object' && e !== {}) ||
          (Array.isArray(e) && e.length > 0)
        ) {
          node[i] = DeepCopy.copy(e);
        }
      });
    } else if (data && typeof data === 'object') {
      node = data instanceof Date ? data : Object.assign({}, data);
      Object.keys(node).forEach((key) => {
        if (
          (typeof node[key] === 'object' && node[key] !== {}) ||
          (Array.isArray(node[key]) && node[key].length > 0)
        ) {
          node[key] = DeepCopy.copy(node[key]);
        }
      });
    } else {
      node = data;
    }
    return node;
  }
}

Импортируйте файл deepCopy в любое место и используйте, как показано ниже, код DeepCopy.copy(arg); , Здесь arg будет либо объект или массив, который вы

Ответ 6

Если источником является массив объектов, используя карту:

let cloned = source.map(x => Object.assign({}, x));

ИЛИ ЖЕ

let cloned = source.map((x) => {
                return { ...x };
             });

Ответ 7

Теперь в js & ts есть намного более синтаксически более удобный способ глубокого клонирования объектов и массивов, поэтому вам не нужно использовать метод stringify unstringify как показано в ответе @GabrielBalsaCantú:

Вы можете использовать оператор распространения для таких объектов:

let obj = {a:1, b:2};
let clone = {...obj};
console.log(clone);
clone.a = 9;
clone.b = 10;
console.log({obj, clone});

Ответ 8

Я столкнулся с проблемой глубокого копирования. angular.copy({}, factory) и angular.extend({}, factory) хорошо помогают для объектов массива или хэширования, но при копировании объекта в calass иногда могут возникать проблемы с подключенными зависимостями. Я решил эту проблему так:

 copyFactory = (() ->
    resource = ->
      resource.__super__.constructor.apply this, arguments
      return
    this.extendTo resource
    resource
  ).call(factory)

Ответ 9

Некоторые модификации для KrishnamrajuK ответа

export class DeepCopy {
  static copy(data: any, objMap?: WeakMap<any, any>) {
    if (!objMap) {
      // Map for handle recursive objects
      objMap = new WeakMap();
    }

    // recursion wrapper
    const deeper = value => {
      if (value && typeof value === 'object') {
        return DeepCopy.copy(value, objMap);
      }
      return value;
    };

    // Array value
    if (Array.isArray(data)) return data.map(deeper);

    // Object value
    if (data && typeof data === 'object') {
      // Same object seen earlier
      if (objMap.has(data)) return objMap.get(data);
      // Date object
      if (data instanceof Date) {
        const result = new Date(data.valueOf());
        objMap.set(data, result);
        return result;
      }
      // Use original prototype
      const node = Object.create(Object.getPrototypeOf(data));
      // Save object to map before recursion
      objMap.set(data, node);
      for (const [key, value] of Object.entries(data)) {
        node[key] = deeper(value);
      }
      return node;
    }
    // Scalar value
    return data;
  }
}

Ответ 10

Я создал очень простую функцию в машинописи, которая принимает все возможные входные данные и дает глубокую клонированную копию этого объекта.

Надеюсь, это кому-нибудь поможет.

  public deepCopy(obj) {

    var clonedObject: any;

    if (obj instanceof Array) {
        var itemArray = Object.assign([], obj);
        clonedObject = itemArray;

        for (var j = 0; j < clonedObject.length; j++) {
            clonedObject[j] = this.deepCopy(clonedObject[j]);
        }

        return clonedObject;
    }
    else if (typeof obj === 'number' || typeof obj == 'string') {
        return obj
    }
    else {


        var item = Object.assign({}, obj);
        clonedObject = item;

        let allKeys = Object.keys(clonedObject);

        for (var i = 0; i < allKeys.length; i++) {
            if (clonedObject[allKeys[i]] instanceof Array) {
                //If the calue is Array
                clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
            }
            else if (clonedObject[allKeys[i]] instanceof Date) {
                clonedObject[allKeys[i]] = new Date(clonedObject[allKeys[i]].valueOf());
            }
            else if (clonedObject[allKeys[i]] instanceof Object){
                //if the value is JOBJECT.
                clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
            }
        }
        return clonedObject;
    }


}