원격 REST 서버에서 JSON 객체를 읽습니다. 이 JSON 객체에는 디자인에 따라 유형 스크립트 클래스의 모든 속성이 있습니다. 수신 된 JSON 객체를 유형 var로 캐스트하는 방법
타입 스크립트 var를 채우고 싶지 않습니다 (즉,이 JSON 객체를 취하는 생성자가 있습니다). 크기가 크며 하위 개체 및 속성별로 속성을 복사하는 데 많은 시간이 걸립니다.
업데이트 : 그러나 타이프 스크립트 인터페이스로 캐스트 할 수 있습니다 !
답변
Ajax 요청의 일반 오래된 JavaScript 결과를 프로토 타입 JavaScript / TypeScript 클래스 인스턴스로 간단히 캐스트 할 수 없습니다. 이를 수행하는 데는 여러 가지 기술이 있으며 일반적으로 데이터 복사가 필요합니다. 클래스의 인스턴스를 만들지 않으면 메서드 나 속성이 없습니다. 간단한 JavaScript 객체로 유지됩니다.
데이터 만 다루는 경우 인터페이스에 캐스트를 수행 할 수 있지만 (순전히 컴파일 시간 구조이므로) 데이터 인스턴스를 사용하고 해당 데이터에 대한 작업을 수행하는 TypeScript 클래스를 사용해야합니다.
데이터 복사의 몇 가지 예 :
본질적으로, 당신은 단지 :
var d = new MyRichObject();
d.copyInto(jsonResult);
답변
나는 같은 문제가 있었고 https://github.com/pleerock/class-transformer 작업을 수행하는 라이브러리를 찾았습니다 .
다음과 같이 작동합니다.
let jsonObject = response.json() as Object;
let fooInstance = plainToClass(Models.Foo, jsonObject);
return fooInstance;
중첩 된 자식을 지원하지만 클래스 멤버를 장식해야합니다.
답변
TypeScript에서는 다음 과 같은 인터페이스와 제네릭을 사용하여 형식 어설 션 을 수행 할 수 있습니다 .
var json = Utilities.JSONLoader.loadFromFile("../docs/location_map.json");
var locations: Array<ILocationMap> = JSON.parse(json).location;
여기서 ILocationMap은 데이터 모양을 설명합니다. 이 방법의 장점은 JSON에 더 많은 속성을 포함 할 수 있지만 모양이 인터페이스의 조건을 충족한다는 것입니다.
도움이 되길 바랍니다.
답변
ES6를 사용하는 경우 다음을 시도하십시오.
class Client{
name: string
displayName(){
console.log(this.name)
}
}
service.getClientFromAPI().then(clientData => {
// Here the client data from API only have the "name" field
// If we want to use the Client class methods on this data object we need to:
let clientWithType = Object.assign(new Client(), clientData)
clientWithType.displayName()
})
그러나 슬프게도이 방법 은 중첩 객체 에서 작동하지 않습니다 .
답변
JSON을 Typescript 클래스로 일반 캐스팅하는 것에 대한 매우 흥미로운 기사를 찾았습니다.
http://cloudmark.github.io/Json-Mapping/
다음 코드로 끝납니다.
let example = {
"name": "Mark",
"surname": "Galea",
"age": 30,
"address": {
"first-line": "Some where",
"second-line": "Over Here",
"city": "In This City"
}
};
MapUtils.deserialize(Person, example); // custom class
답변
TLDR : 하나의 라이너
// This assumes your constructor method will assign properties from the arg.
.map((instanceData: MyClass) => new MyClass(instanceData));
자세한 답변
나는 것 없는 이 클래스 자체 내에서 부적절 쓰레기 수업 관련이없는 속성이 예 (뿐만 아니라 정의 폐쇄) 선언되지 않은 수대로 Object.assign 방법을 추천합니다.
역 직렬화하려는 클래스에서 역 직렬화하려는 속성이 정의되어 있는지 확인합니다 (null, empty array 등). 초기 값으로 속성을 정의하면 클래스 멤버를 반복하여 값을 할당하려고 할 때 가시성을 노출합니다 (아래의 직렬화 해제 방법 참조).
export class Person {
public name: string = null;
public favoriteSites: string[] = [];
private age: number = null;
private id: number = null;
private active: boolean;
constructor(instanceData?: Person) {
if (instanceData) {
this.deserialize(instanceData);
}
}
private deserialize(instanceData: Person) {
// Note this.active will not be listed in keys since it's declared, but not defined
const keys = Object.keys(this);
for (const key of keys) {
if (instanceData.hasOwnProperty(key)) {
this[key] = instanceData[key];
}
}
}
}
위의 예에서 간단히 deserialize 메서드를 만들었습니다. 실제 예에서는 재사용 가능한 기본 클래스 또는 서비스 방법으로 중앙 집중화해야합니다.
여기에 http resp와 같은 것을 사용하는 방법이 있습니다 …
this.http.get(ENDPOINT_URL)
.map(res => res.json())
.map((resp: Person) => new Person(resp) ) );
tslint / ide가 인수 유형이 호환되지 않는다고 불평하는 경우, 꺾쇠 괄호를 사용하여 인수를 동일한 유형으로 캐스트하십시오 ( <YourClassName>
예 :
const person = new Person(<Person> { name: 'John', age: 35, id: 1 });
특정 유형의 클래스 멤버 (일명 : 다른 클래스의 인스턴스)가있는 경우 getter / setter 메소드를 통해 유형이 지정된 인스턴스로 캐스트 할 수 있습니다.
export class Person {
private _acct: UserAcct = null;
private _tasks: Task[] = [];
// ctor & deserialize methods...
public get acct(): UserAcct {
return this.acct;
}
public set acct(acctData: UserAcct) {
this._acct = new UserAcct(acctData);
}
public get tasks(): Task[] {
return this._tasks;
}
public set tasks(taskData: Task[]) {
this._tasks = taskData.map(task => new Task(task));
}
}
위의 예제는 acct와 작업 목록을 각각의 클래스 인스턴스로 역 직렬화합니다.
답변
json에 typescript 클래스와 동일한 속성이 있다고 가정하면 Json 속성을 typescript 객체에 복사 할 필요가 없습니다. 생성자에서 json 데이터를 전달하는 Typescript 객체를 구성해야합니다.
Ajax 콜백에서 회사를받습니다 :
onReceiveCompany( jsonCompany : any )
{
let newCompany = new Company( jsonCompany );
// call the methods on your newCompany object ...
}
그 일을하기 위해 :
1) json 데이터를 매개 변수로 사용하는 생성자를 Typescript 클래스에 추가하십시오. 해당 생성자에서 다음과 같이 jQuery로 json 객체를 확장합니다 $.extend( this, jsonData)
. $ .extend를 사용하면 json 객체의 속성을 추가하면서 자바 스크립트 프로토 타입을 유지할 수 있습니다.
2) 연결된 객체에 대해서도 동일한 작업을 수행해야합니다. 예제의 Employees의 경우 직원에 대한 json 데이터의 일부를 사용하는 생성자를 작성하십시오. json 직원을 typescript Employee 객체로 변환하려면 $ .map을 호출하십시오.
export class Company
{
Employees : Employee[];
constructor( jsonData: any )
{
$.extend( this, jsonData);
if ( jsonData.Employees )
this.Employees = $.map( jsonData.Employees , (emp) => {
return new Employee ( emp ); });
}
}
export class Employee
{
name: string;
salary: number;
constructor( jsonData: any )
{
$.extend( this, jsonData);
}
}
이것이 Typescript 클래스와 json 객체를 다룰 때 찾은 최고의 솔루션입니다.