简体   繁体   English

儿童模型吸气剂和二传手不能以角度2/4工作

[英]Child model getter and setter are not working in angular 2/4

I have a situation where I have defined three model classes as below 我有一种情况,我已经定义了三个模型类,如下所示

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;
    }
}

The problem is: the getter and setter method of Set class wouldn't get triggered unless I do new Set() explicitly (I don't know if the new Set() this is really necessary). 问题是:除非我明确地执行new Set()否则不会触发Set类的gettersetter方法(我不知道new Set()是否真的有必要)。

For example: 例如:

"name": "vik",
"containers": [
{
    "desc": "something",
    "sets": [
    {
        "dataSet": [
        {
            "data":[
            {
                // Object
            }]
        }]
    }]
}]

When i do: 当我做:

let response:Parent = responseObj;
console.log(response.containers[0].sets[0].data)

it should return the DataSet value , but instead it returns undefined . 它应该返回DataSet value ,而是返回undefined

But if i do: 但如果我这样做:

let response:Parent = responseObj;
console.log(new Sets(response.containers[0].sets[0]).data)

returns me the correct value. 返回正确的值。

Did I miss something or how could I improve my code so it works? 我错过了什么或者我如何改进我的代码以便它有效?

The problem is that your object comes from HTTP. 问题是你的对象来自HTTP。 What does this mean: 这是什么意思:

Http is a text based format. Http是一种基于文本的格式。 This means that when response comes to you it is an only string like: 这意味着当响应发生时,它是一个唯一的字符串,如:

"{"foo":"boor"}"

Then you do smth like JSON.parse(data) and return real object like: 然后你像JSON.parse(数据)一样smth并返回真实对象,如:

{foo: "bar"};

But JSON.parse does no nothing about type you expected. 但是JSON.parse对你预期的类型没有任何意义。 It doesn't know how to make from string instance of the object. 它不知道如何从对象的字符串实例。 It can just try to make a simple object and this is all. 它可以尝试制作一个简单的对象,这就是全部。

You see, your data object has no information about it's type, methods, getter/setters etc It is just about plane data aka dto. 你看,你的数据对象没有关于它的类型,方法,getter / setter等的信息。它只是关于平面数据aka dto。 So, if you want to get real classes from your dto you should write smarter parser, that will take your dto and create from it real instance of the expected class. 所以,如果你想从你的dto获得真正的类,你应该编写更聪明的解析器,这将带你的dto并从它创建预期类的真实实例。 Basically you already do this by 基本上你已经这样做了

new Sets(response.containers[0].sets[0])

So you can keep doing this, but than you will find that this repetitive code is all around your application. 所以你可以继续这样做,但是你会发现这个重复的代码都在你的应用程序周围。 The best way I found is to inject mapper to the data server and return not dto but an instance. 我找到的最好方法是将mapper注入数据服务器并返回不是dto而是返回实例。 So your other code will no nothing about this "dirty" work and will always works with "normal" objects. 因此,您的其他代码对此“脏”工作一无所知,并且始终适用于“普通”对象。

Hope this helps. 希望这可以帮助。

UPD: UPD:

 let rawData = '{"name":"Vitalii"}'; let person1 = JSON.parse(rawData); function Person(data) { this.name = data.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 

This is because this object have a different nature even if they looks similar. 这是因为即使它们看起来相似,该对象也具有不同的性质。

Yes, you have to (somehow) parse your plain object to class instance you defined, others has already answered it for you. 是的,您必须(以某种方式)将您的普通对象解析为您定义的类实例,其他人已经为您解答了它。

So I just suggest one way of refactoring: 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
}

and then 然后

let response:Parent = responseObj;
console.log(Parent.fromJson(response).containers[0].sets[0].data)

this is much neater, I think 我觉得这个更整洁

hope this help~ 希望这个帮助〜

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM