Angular.copy의 Angular.copy에 대한 대안은 무엇입니까?
Angular에서 개체를 복사하고 참조를 손실하려면 어떻게 해야 합니까?
AngularJS를 사용하면,angular.copy(object)
Angular에서 사용하는 오류가 발생했습니다.
예외:참조 오류:
angular
정의되지 않음
ES6를 사용하고 있다고 가정하면,var copy = Object.assign({}, original)
최신 브라우저에서 작동합니다. 이전 브라우저를 지원해야 하는 경우 이 폴리필을 확인하십시오.
업데이트:
TypeScript 2.1+에서는 ES6 단축 개체 확산 표기법을 사용할 수 있습니다.
const copy = { ...original }
더 나은 솔루션이 나올 때까지 다음을 사용할 수 있습니다.
duplicateObject = <YourObjType> JSON.parse(JSON.stringify(originalObject));
편집: 설명
참고:위의 솔루션은 Angular 2가 활성화된 시기에 제공되는 신속한 수정을 위한 하나의 라이너입니다.제 희망은 우리가 결국에는 그에 상응하는 것을 얻는 것이었습니다.angular.copy()
따라서 저는 딥 클로닝 라이브러리를 작성하거나 가져오기를 원하지 않았습니다.
이 메서드는 또한 날짜 속성을 구문 분석하는 데 문제가 있습니다(문자열이 됨).
프로덕션 앱에서 이 방법을 사용하지 마십시오.Angular 2를 학습하기 위해 수행 중인 실험 프로젝트에서만 사용하십시오.
내부에 중첩된 개체가 있는 개체를 딥 복사하는 방법은 lodash의 cloneDeep 메서드를 사용하는 것입니다.
Angular의 경우 다음과 같이 수행할 수 있습니다.
로다쉬 설치하기yarn add lodash
또는npm install lodash
.
구성 요소에서 가져오기cloneDeep
사용:
import { cloneDeep } from "lodash";
...
clonedObject = cloneDeep(originalObject);
빌드에 18kb만 추가되므로 이점을 누릴 수 있습니다.
Lodash의 클론 Deep를 사용하는 이유에 대한 자세한 정보가 필요한 경우 여기에 기사를 작성했습니다.
얕은 복사의 경우 ES6 기능인 Object.assign을 사용할 수 있습니다.
let x = { name: 'Marek', age: 20 };
let y = Object.assign({}, x);
x === y; //false
딥 클로닝에 사용 안 함
표시된 대로 lodash를 사용합니다.Angular에 더 이상 이 방법이 없는 이유는 Angular 1이 독립적인 프레임워크였고 외부 라이브러리가 종종 Angular 실행 컨텍스트와 관련된 문제에 부딪혔기 때문입니다.Angular 2는 그런 문제가 없으므로 원하는 라이브러리를 사용하십시오.
https://lodash.com/docs#cloneDeep
제가 찾은 가장 간단한 해결책은 다음과 같습니다.
let yourDeepCopiedObject = _.cloneDeep(yourOriginalObject);
*중요 단계:이를 사용하려면 Lodash를 설치해야 합니다(다른 답변에서는 명확하지 않음).
$ npm install --save lodash
$ npm install --save @types/lodash
그런 다음 ts 파일로 가져옵니다.
import * as _ from "lodash";
클래스 인스턴스를 복사하려면 Object.assign도 사용할 수 있지만 새 인스턴스를 첫 번째 매개 변수({} 대신)로 전달해야 합니다.
class MyClass {
public prop1: number;
public prop2: number;
public summonUnicorn(): void {
alert('Unicorn !');
}
}
let instance = new MyClass();
instance.prop1 = 12;
instance.prop2 = 42;
let wrongCopy = Object.assign({}, instance);
console.log(wrongCopy.prop1); // 12
console.log(wrongCopy.prop2); // 42
wrongCopy.summonUnicorn() // ERROR : undefined is not a function
let goodCopy = Object.assign(new MyClass(), instance);
console.log(goodCopy.prop1); // 12
console.log(goodCopy.prop2); // 42
goodCopy.summonUnicorn() // It works !
다른 사람들이 이미 지적했듯이, 로다쉬나 밑줄을 사용하는 것이 아마도 가장 좋은 해결책일 것입니다.그러나 다른 용도로 이러한 라이브러리가 필요하지 않다면 다음과 같은 것을 사용할 수 있습니다.
function deepClone(obj) {
// return value is input is not an Object or Array.
if (typeof(obj) !== 'object' || obj === null) {
return obj;
}
let clone;
if(Array.isArray(obj)) {
clone = obj.slice(); // unlink Array reference.
} else {
clone = Object.assign({}, obj); // Unlink Object reference.
}
let keys = Object.keys(clone);
for (let i=0; i<keys.length; i++) {
clone[keys[i]] = deepClone(clone[keys[i]]); // recursively unlink reference to nested objects.
}
return clone; // return unlinked clone.
}
그게 우리가 결정한 거다. .
let newObj = JSON.parse(JSON.stringify(obj))
그JSON.stringify()
합니다.
다음과 같이 어레이를 복제할 수 있습니다.
this.assignCustomerList = Object.assign([], this.customerList);
그리고 다음과 같이 개체를 복제합니다.
this.assignCustomer = Object.assign({}, this.customer);
수 있는 . Angular 5를 합니다. 그것은 다음을 사용합니다.angular.copy()
앵귤러 제이에스의 베이스, 저에게 잘 맞습니다.추가적으로, 다음과 같은 다른 기능이 있습니다.isUndefined
. 도움이 되었으면 좋겠습니다.다른 최적화와 마찬가지로, 알아두면 좋을 것입니다.안부 전해요
import { Injectable } from '@angular/core';
@Injectable({providedIn: 'root'})
export class AngularService {
private TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/;
private stackSource = [];
private stackDest = [];
constructor() { }
public isNumber(value: any): boolean {
if ( typeof value === 'number' ) { return true; }
else { return false; }
}
public isTypedArray(value: any) {
return value && this.isNumber(value.length) && this.TYPED_ARRAY_REGEXP.test(toString.call(value));
}
public isArrayBuffer(obj: any) {
return toString.call(obj) === '[object ArrayBuffer]';
}
public isUndefined(value: any) {return typeof value === 'undefined'; }
public isObject(value: any) { return value !== null && typeof value === 'object'; }
public isBlankObject(value: any) {
return value !== null && typeof value === 'object' && !Object.getPrototypeOf(value);
}
public isFunction(value: any) { return typeof value === 'function'; }
public setHashKey(obj: any, h: any) {
if (h) { obj.$$hashKey = h; }
else { delete obj.$$hashKey; }
}
private isWindow(obj: any) { return obj && obj.window === obj; }
private isScope(obj: any) { return obj && obj.$evalAsync && obj.$watch; }
private copyRecurse(source: any, destination: any) {
const h = destination.$$hashKey;
if (Array.isArray(source)) {
for (let i = 0, ii = source.length; i < ii; i++) {
destination.push(this.copyElement(source[i]));
}
} else if (this.isBlankObject(source)) {
for (const key of Object.keys(source)) {
destination[key] = this.copyElement(source[key]);
}
} else if (source && typeof source.hasOwnProperty === 'function') {
for (const key of Object.keys(source)) {
destination[key] = this.copyElement(source[key]);
}
} else {
for (const key of Object.keys(source)) {
destination[key] = this.copyElement(source[key]);
}
}
this.setHashKey(destination, h);
return destination;
}
private copyElement(source: any) {
if (!this.isObject(source)) {
return source;
}
const index = this.stackSource.indexOf(source);
if (index !== -1) {
return this.stackDest[index];
}
if (this.isWindow(source) || this.isScope(source)) {
throw console.log('Cant copy! Making copies of Window or Scope instances is not supported.');
}
let needsRecurse = false;
let destination = this.copyType(source);
if (destination === undefined) {
destination = Array.isArray(source) ? [] : Object.create(Object.getPrototypeOf(source));
needsRecurse = true;
}
this.stackSource.push(source);
this.stackDest.push(destination);
return needsRecurse
? this.copyRecurse(source, destination)
: destination;
}
private copyType = (source: any) => {
switch (toString.call(source)) {
case '[object Int8Array]':
case '[object Int16Array]':
case '[object Int32Array]':
case '[object Float32Array]':
case '[object Float64Array]':
case '[object Uint8Array]':
case '[object Uint8ClampedArray]':
case '[object Uint16Array]':
case '[object Uint32Array]':
return new source.constructor(this.copyElement(source.buffer), source.byteOffset, source.length);
case '[object ArrayBuffer]':
if (!source.slice) {
const copied = new ArrayBuffer(source.byteLength);
new Uint8Array(copied).set(new Uint8Array(source));
return copied;
}
return source.slice(0);
case '[object Boolean]':
case '[object Number]':
case '[object String]':
case '[object Date]':
return new source.constructor(source.valueOf());
case '[object RegExp]':
const re = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
re.lastIndex = source.lastIndex;
return re;
case '[object Blob]':
return new source.constructor([source], {type: source.type});
}
if (this.isFunction(source.cloneNode)) {
return source.cloneNode(true);
}
}
public copy(source: any, destination?: any) {
if (destination) {
if (this.isTypedArray(destination) || this.isArrayBuffer(destination)) {
throw console.log('Cant copy! TypedArray destination cannot be mutated.');
}
if (source === destination) {
throw console.log('Cant copy! Source and destination are identical.');
}
if (Array.isArray(destination)) {
destination.length = 0;
} else {
destination.forEach((value: any, key: any) => {
if (key !== '$$hashKey') {
delete destination[key];
}
});
}
this.stackSource.push(source);
this.stackDest.push(destination);
return this.copyRecurse(source, destination);
}
return this.copyElement(source);
}
}
앱 '모델'(원시 백엔드 데이터를 객체로 변환)에서 이 기능이 필요했습니다.그래서 Object.create(지정된 프로토타입에서 새 개체 만들기)와 Object.assign(개체 간 속성 복사)의 조합을 사용하게 되었습니다.딥 복사본을 수동으로 처리해야 합니다.저는 이것을 위한 요지를 만들었습니다.
npm 패키지를 사용할 수 있는 경우 "ngx-scv-util"을 사용할 수 있습니다.
다음 명령을 실행하여 패키지를 설치합니다.
npm i ngx-scv-util --save
다음을 사용하여 패키지를 구성 요소로 가져옵니다.
import { NgxScvUtil } from "ngx-scv-util";
....
constructor(private util: NgxScvUtil) {}
용도:
let newObject = this.util.deepCopy(originalObject);
그것은 매우 가벼운 패키지입니다.자세한 내용은 https://www.npmjs.com/package/ngx-scv-util 에서 확인할 수 있습니다.
동일한 문제가 발생했으며 딥 클로닝에만 플러그인을 사용하고 싶지 않았습니다.
static deepClone(object): any {
const cloneObj = (<any>object.constructor());
const attributes = Object.keys(object);
for (const attribute of attributes) {
const property = object[attribute];
if (typeof property === 'object') {
cloneObj[attribute] = this.deepClone(property);
} else {
cloneObj[attribute] = property;
}
}
return cloneObj;
}
학점:이 기능을 더 읽기 쉽게 만들었습니다. 아래 기능의 예외 사항을 확인하십시오.
나뿐만 아니라 당신도 작업 angular.copy 및 angular.expect의 문제에 직면했습니다. 왜냐하면 그들은 일부 종속성을 추가하지 않고 객체를 복사하거나 만들지 않기 때문입니다.제 해결책은 다음과 같습니다.
copyFactory = (() ->
resource = ->
resource.__super__.constructor.apply this, arguments
return
this.extendTo resource
resource
).call(factory)
만약 당신이 아직 lodash를 사용하고 있지 않다면 나는 이 한 가지 방법에만 설치하는 것을 추천하지 않을 것입니다.대신 'clone'과 같은 보다 좁은 전문화 라이브러리를 제안합니다.
npm install clone
언급URL : https://stackoverflow.com/questions/34688517/whats-alternative-to-angular-copy-in-angular
'programing' 카테고리의 다른 글
루비 온 레일즈에서 세터 방법을 재정의하는 올바른 방법은 무엇입니까? (0) | 2023.06.01 |
---|---|
SQL Server 연결 문자열을 설정하려면 어떻게 해야 합니까? (0) | 2023.06.01 |
루비에서 'continue'와 유사한 .each 루프에서 루프를 건너뛰려면 어떻게 해야 합니까? (0) | 2023.06.01 |
오류: 모듈에서 예기치 않은 값 '정의되지 않음'을(를) 가져왔습니다. (0) | 2023.06.01 |
Ruby에서 파일 이름 및 확장자 가져오기 (0) | 2023.06.01 |