子模型 getter 和 setter 在 angular 中不工作 2/4
Child model getter and setter are not working in angular 2/4
我有一种情况,我定义了三个模型 classes
export class Parent
{
name: string;
containers: Container[];
}
export class Container
{
desc: string;
sets: Sets[];
}
export class Sets
{
private _data?: any[];
private _dataSet?: any[];
get data()
{
if (this.dataSet && this.dataSet.length > 0)
{
return this._dataSet[0].data;
}
return this._data;
}
set data(data: any[])
{
this._data = data;
}
get dataSet()
{
return this._dataSet;
}
set dataSet(dataSet: any[])
{
this._dataSet = dataSet;
}
}
问题是:Set
class 的 getter
和 setter
方法不会被触发,除非我明确地 new Set()
(我不'才知道new Set()
这个真的有必要)。
例如:
"name": "vik",
"containers": [
{
"desc": "something",
"sets": [
{
"dataSet": [
{
"data":[
{
// Object
}]
}]
}]
}]
当我这样做时:
let response:Parent = responseObj;
console.log(response.containers[0].sets[0].data)
它应该 return 数据集 value
,但它 return 是 undefined
。
但如果我这样做:
let response:Parent = responseObj;
console.log(new Sets(response.containers[0].sets[0]).data)
return告诉我正确的值。
我是不是遗漏了什么或者我如何改进我的代码才能正常工作?
问题是您的对象来自 HTTP。这是什么意思:
Http 是一种基于文本的格式。这意味着当您收到响应时,它是唯一的字符串,例如:
"{"foo":"boor"}"
然后你像JSON.parse(数据)和return这样的真实对象做smth像:
{foo: "bar"};
但是 JSON.parse 对您期望的 type 没有任何作用。它不知道如何从对象的字符串实例中生成。它可以尝试制作一个简单的对象,仅此而已。
你看,你的数据对象没有关于它的类型、方法、getter/setters e.t.c 的信息。它只是关于平面数据又名 dto。所以,如果你想从你的 dto 中获得真实的 classes,你应该编写更智能的解析器,它将获取你的 dto 并从中创建预期 class 的真实实例。
基本上你已经通过
做到了
new Sets(response.containers[0].sets[0])
所以您可以继续这样做,但是您会发现这些重复的代码遍布您的应用程序。我发现最好的方法是将 mapper 注入数据服务器并且 return 不是 dto 而是一个实例。因此,您的其他代码不会对这种“肮脏”的工作一无所知,并且将始终与“正常”对象一起工作。
希望对您有所帮助。
更新:
const rawData = '{"name":"Vitalii"}';
const person1 = JSON.parse(rawData);
function Person({name}) {
this.name = name;
this.say = function() {
console.log(`Hi, ${this.name}`);
}
}
let person2 = new Person(person1);
person2.say();
// person1 and person2 have the same data inside. But:
console.log(person2 instanceof Person); // true
console.log(person1 instanceof Person); // false
这是因为这个物体虽然看起来很相似,但性质不同。
是的,您必须(以某种方式)将普通对象解析为您定义的 class 实例,其他人已经为您解答了。
所以我只建议一种重构方式:nested object of class transformer
import { Type, plainToClass } from 'class-transformer';
export class Parent {
@Type(() => Container)
name: string;
containers: Container[] = [];
static fromJson(json: any): Parent {
return plainToClass<any, Parent>(Parent, json);
}
}
export class Container{
@Type(() => Set)
desc: string;
sets: Set[] = [];
}
export class Set{
private _data?: any[];
private _dataSet?: any[];
//your code
}
然后
let response:Parent = responseObj;
console.log(Parent.fromJson(response).containers[0].sets[0].data)
我觉得这样更简洁
希望能帮到你~
我有一种情况,我定义了三个模型 classes
export class Parent
{
name: string;
containers: Container[];
}
export class Container
{
desc: string;
sets: Sets[];
}
export class Sets
{
private _data?: any[];
private _dataSet?: any[];
get data()
{
if (this.dataSet && this.dataSet.length > 0)
{
return this._dataSet[0].data;
}
return this._data;
}
set data(data: any[])
{
this._data = data;
}
get dataSet()
{
return this._dataSet;
}
set dataSet(dataSet: any[])
{
this._dataSet = dataSet;
}
}
问题是:Set
class 的 getter
和 setter
方法不会被触发,除非我明确地 new Set()
(我不'才知道new Set()
这个真的有必要)。
例如:
"name": "vik",
"containers": [
{
"desc": "something",
"sets": [
{
"dataSet": [
{
"data":[
{
// Object
}]
}]
}]
}]
当我这样做时:
let response:Parent = responseObj;
console.log(response.containers[0].sets[0].data)
它应该 return 数据集 value
,但它 return 是 undefined
。
但如果我这样做:
let response:Parent = responseObj;
console.log(new Sets(response.containers[0].sets[0]).data)
return告诉我正确的值。
我是不是遗漏了什么或者我如何改进我的代码才能正常工作?
问题是您的对象来自 HTTP。这是什么意思:
Http 是一种基于文本的格式。这意味着当您收到响应时,它是唯一的字符串,例如:
"{"foo":"boor"}"
然后你像JSON.parse(数据)和return这样的真实对象做smth像:
{foo: "bar"};
但是 JSON.parse 对您期望的 type 没有任何作用。它不知道如何从对象的字符串实例中生成。它可以尝试制作一个简单的对象,仅此而已。
你看,你的数据对象没有关于它的类型、方法、getter/setters e.t.c 的信息。它只是关于平面数据又名 dto。所以,如果你想从你的 dto 中获得真实的 classes,你应该编写更智能的解析器,它将获取你的 dto 并从中创建预期 class 的真实实例。 基本上你已经通过
做到了new Sets(response.containers[0].sets[0])
所以您可以继续这样做,但是您会发现这些重复的代码遍布您的应用程序。我发现最好的方法是将 mapper 注入数据服务器并且 return 不是 dto 而是一个实例。因此,您的其他代码不会对这种“肮脏”的工作一无所知,并且将始终与“正常”对象一起工作。
希望对您有所帮助。
更新:
const rawData = '{"name":"Vitalii"}';
const person1 = JSON.parse(rawData);
function Person({name}) {
this.name = name;
this.say = function() {
console.log(`Hi, ${this.name}`);
}
}
let person2 = new Person(person1);
person2.say();
// person1 and person2 have the same data inside. But:
console.log(person2 instanceof Person); // true
console.log(person1 instanceof Person); // false
这是因为这个物体虽然看起来很相似,但性质不同。
是的,您必须(以某种方式)将普通对象解析为您定义的 class 实例,其他人已经为您解答了。
所以我只建议一种重构方式:nested object of class transformer
import { Type, plainToClass } from 'class-transformer';
export class Parent {
@Type(() => Container)
name: string;
containers: Container[] = [];
static fromJson(json: any): Parent {
return plainToClass<any, Parent>(Parent, json);
}
}
export class Container{
@Type(() => Set)
desc: string;
sets: Set[] = [];
}
export class Set{
private _data?: any[];
private _dataSet?: any[];
//your code
}
然后
let response:Parent = responseObj;
console.log(Parent.fromJson(response).containers[0].sets[0].data)
我觉得这样更简洁
希望能帮到你~