子模型 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 的 gettersetter 方法不会被触发,除非我明确地 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)

我觉得这样更简洁

希望能帮到你~