JSON에서 TypeScript 클래스 인스턴스로? [복제]
이 질문에 이미 답변이 있습니다.
나는 꽤 많은 연구를했지만 내가 찾은 것에 완전히 만족하지 않습니다. 여기에 내 질문이 있습니다. 실제로 JSON에서 TypeScript 런타임 클래스 인스턴스로 deserialize하는 가장 강력하고 우아한 자동화 솔루션은 무엇입니까?
이 수업을 받았다고 가정하십시오.
class Foo {
name: string;
GetName(): string { return this.name };
}
그리고 역 직렬화를 위해이 JSON 문자열을 얻었다 고합니다.
{"name": "John Doe"}
이름이 "John Doe"로 설정된 Foo 클래스의 인스턴스를 가져오고 GetName () 메서드가 작동하도록하는 가장 좋고 유지 관리가 쉬운 솔루션은 무엇입니까? 순수한 데이터 개체로 역 직렬화하는 것이 쉽기 때문에 매우 구체적으로 묻고 있습니다. 수동 구문 분석이나 수동 데이터 복사를 수행하지 않고도 작업 메서드를 사용하여 클래스 인스턴스를 얻을 수 있는지 궁금합니다. 완전 자동화 된 솔루션이 불가능하다면 차선책은 무엇입니까?
이 질문은 매우 광범위하므로 몇 가지 해결책을 제시하겠습니다.
해결 방법 1 : 도우미 방법
다음은 필요에 맞게 변경할 수있는 도우미 메서드를 사용하는 예입니다.
class SerializationHelper {
static toInstance<T>(obj: T, json: string) : T {
var jsonObj = JSON.parse(json);
if (typeof obj["fromJSON"] === "function") {
obj["fromJSON"](jsonObj);
}
else {
for (var propName in jsonObj) {
obj[propName] = jsonObj[propName]
}
}
return obj;
}
}
그런 다음 사용 :
var json = '{"name": "John Doe"}',
foo = SerializationHelper.toInstance(new Foo(), json);
foo.GetName() === "John Doe";
고급 역 직렬화
이것은 또한 fromJSON
클래스에 자신의 메서드를 추가하여 일부 사용자 지정 역 직렬화를 허용 할 수 있습니다 (표시되는 것처럼 메서드를 JSON.stringify
이미 사용하는 toJSON
방식 과 잘 작동합니다 ).
interface IFooSerialized {
nameSomethingElse: string;
}
class Foo {
name: string;
GetName(): string { return this.name }
toJSON(): IFooSerialized {
return {
nameSomethingElse: this.name
};
}
fromJSON(obj: IFooSerialized) {
this.name = obj.nameSomethingElse;
}
}
그런 다음 사용 :
var foo1 = new Foo();
foo1.name = "John Doe";
var json = JSON.stringify(foo1);
json === '{"nameSomethingElse":"John Doe"}';
var foo2 = SerializationHelper.toInstance(new Foo(), json);
foo2.GetName() === "John Doe";
솔루션 2 : 기본 클래스
이를 수행 할 수있는 또 다른 방법은 고유 한 기본 클래스를 만드는 것입니다.
class Serializable {
fillFromJSON(json: string) {
var jsonObj = JSON.parse(json);
for (var propName in jsonObj) {
this[propName] = jsonObj[propName]
}
}
}
class Foo extends Serializable {
name: string;
GetName(): string { return this.name }
}
그런 다음 사용 :
var foo = new Foo();
foo.fillFromJSON(json);
기본 클래스를 사용하여 사용자 지정 역 직렬화를 구현하는 데는 너무 많은 방법이 있으므로 원하는 방식으로 남겨 두겠습니다.
이제 Object.assign(target, ...sources)
. 귀하의 예에 따라 다음과 같이 사용할 수 있습니다.
class Foo {
name: string;
getName(): string { return this.name };
}
let fooJson: string = '{"name": "John Doe"}';
let foo: Foo = Object.assign(new Foo(), JSON.parse(fooJson));
console.log(foo.getName()); //returns John Doe
Object.assign
ECMAScript 2015의 일부 이며 현재 대부분의 최신 브라우저에서 사용할 수 있습니다.
JSON을 TypeScript 런타임 클래스 인스턴스로 역 직렬화하는 데 실제로 가장 강력하고 우아한 자동화 솔루션은 무엇입니까?
Using property decorators with ReflectDecorators to record runtime-accessible type information that can be used during a deserialization process provides a surprisingly clean and widely adaptable approach, that also fits into existing code beautifully. It is also fully automatable, and works for nested objects as well.
An implementation of this idea is TypedJSON, which I created precisely for this task:
@JsonObject
class Foo {
@JsonMember
name: string;
getName(): string { return this.name };
}
var foo = TypedJSON.parse('{"name": "John Doe"}', Foo);
foo instanceof Foo; // true
foo.getName(); // "John Doe"
Why could you not just do something like this?
class Foo {
constructor(myObj){
Object.assign(this, myObj);
}
get name() { return this._name; }
set name(v) { this._name = v; }
}
let foo = new Foo({ name: "bat" });
foo.toJSON() //=> your json ...
The best solution I found when dealing with Typescript classes and json objects: add a constructor in your Typescript class that takes the json data as parameter. In that constructor you extend your json object with jQuery, like this: $.extend( this, jsonData). $.extend allows keeping the javascript prototypes while adding the json object's properties.
export class Foo
{
Name: string;
getName(): string { return this.Name };
constructor( jsonFoo: any )
{
$.extend( this, jsonFoo);
}
}
In your ajax callback, translate your jsons in a your typescript object like this:
onNewFoo( jsonFoos : any[] )
{
let receviedFoos = $.map( jsonFoos, (json) => { return new Foo( json ); } );
// then call a method:
let firstFooName = receviedFoos[0].GetName();
}
If you don't add the constructor, juste call in your ajax callback:
let newFoo = new Foo();
$.extend( newFoo, jsonData);
let name = newFoo.GetName()
...but the constructor will be useful if you want to convert the children json object too. See my detailed answer here.
참고URL : https://stackoverflow.com/questions/29758765/json-to-typescript-class-instance
'IT박스' 카테고리의 다른 글
MKAnnotationView의 콜 아웃 풍선을 사용자 정의하는 방법은 무엇입니까? (0) | 2020.09.10 |
---|---|
try-except 블록과 함께 파이썬 "with"문 사용 (0) | 2020.09.10 |
Razor보기에서 문자열 보간? (0) | 2020.09.10 |
트램폴린 기능은 무엇입니까? (0) | 2020.09.10 |
자바 동적 바인딩 및 메서드 재정의 (0) | 2020.09.10 |