Угловой JS имеет angular.copy()
для глубоких копий объектов и массивов.
Есть ли у Angular что-то вроде этого?
Угловой JS имеет angular.copy()
для глубоких копий объектов и массивов.
Есть ли у Angular что-то вроде этого?
Вы также можете использовать:
JSON.parse(JSON.stringify(Object))
если он находится в вашей области видимости, в каждом компоненте Angular, директиве и т.д., а также в каждой среде node.
Если у вас нет циркулярной ссылки, она должна работать и эффективно отделяет вашу ссылку на исходный объект.
Другой вариант - реализовать собственную функцию:
/**
* 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;
}
Этот вопрос не является дубликатом Как я могу использовать angular.copy в angular 2, потому что OP спрашивает о глубоком копировании объектов. В связанном ответе рекомендуется Object.assign(), который не делает глубокую копию.
На самом деле, использование Angular2 не ограничивает вас от использования других библиотек, таких как jQuery, для глубокого копирования объектов с их функцией $.clone() или lodash с _.cloneDeep().
У наиболее распространенных библиотек есть свои типизации, доступные через инструменты CLI, поэтому даже при переносе из TypeScript вы можете легко использовать все, что захотите.
Также смотрите: Каков наиболее эффективный способ глубокого клонирования объекта в JavaScript?
Вы можете 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.
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 будет либо объект или массив, который вы
Если источником является массив объектов, используя карту:
let cloned = source.map(x => Object.assign({}, x));
ИЛИ ЖЕ
let cloned = source.map((x) => {
return { ...x };
});
Теперь в 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});
Я столкнулся с проблемой глубокого копирования. angular.copy({}, factory) и angular.extend({}, factory) хорошо помогают для объектов массива или хэширования, но при копировании объекта в calass иногда могут возникать проблемы с подключенными зависимостями. Я решил эту проблему так:
copyFactory = (() ->
resource = ->
resource.__super__.constructor.apply this, arguments
return
this.extendTo resource
resource
).call(factory)
Некоторые модификации для 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;
}
}
Я создал очень простую функцию в машинописи, которая принимает все возможные входные данные и дает глубокую клонированную копию этого объекта.
Надеюсь, это кому-нибудь поможет.
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;
}
}