简体   繁体   English

TypeScript:带有构造函数的类,该构造函数根据传入的参数调用方法

[英]TypeScript: class with a constructor which calls methods depending incoming parameter

I have a regular TS class looking like this: 我有一个常规的TS课,看起来像这样:

export class Company {
  private firmId: number;
  private regNr: string;
  private firmName: string;
  private address: string;
  private status: string;
  private town: string;
  private zip: string;
  private postAddress: string;
  private tel1: string;
  private tel2: string;
  private fax: string;
  private eMail: string;
  private homepage: string;
  private webshow: string;
  private bankcode: string;
  private bankaccount: string;
  private contact: string;
  private addidata: string;
  private entryDate: string;
  private userId: string;
  private infoEMail: string;
  private pfId: string;
  private pfName: string;
  private country: string;

  constructor(company: any) {
    this.firmId = company.firmId;
    this.regNr = company.regNr;
    this.firmName = company.firmName;
    this.address = company.address;
    this.status = company.status;
    this.town = company.town;
    this.zip = company.zip;
    this.postAddress = company.postAddress;
    this.tel1 = company.tel1;
    this.tel2 = company.tel2;
    this.fax = company.fax;
    this.eMail = company.eMail;
    this.homepage = company.homepage;
    this.webshow = company.webshow;
    this.bankcode = company.bankcode;
    this.bankaccount = company.bankaccount;
    this.contact = company.contact;
    this.addidata = company.addidata;
    this.entryDate = company.entryDate;
    this.userId = company.userId;
    this.infoEMail = company.infoEMail;
    this.pfId = company.pfId;
    this.pfName = company.pfName;
    this.country = company.country;
  }
}

This constructor is obviously very fat and I am considering refactoring to builder pattern, but for now it is like this. 这个构造函数显然很胖,我正在考虑将其重构为构造器模式,但是现在它就像这样。

This class is instantiated with a JSON response, that has absolutely the same field structure. 此类使用JSON响应实例化,该响应具有完全相同的字段结构。

The problem arises when I need to instantiate this class with empty values in order for Angular form validation to work correctly. 当我需要使用空值实例化此类以使Angular表单验证正常工作时,就会出现问题。

How can I achieve that? 我该如何实现? Can I create a constructor which calls the methods of this class depending upon the constructor parameters, something like this: 我可以创建一个构造函数,该构造函数根据构造函数参数来调用此类的方法,如下所示:

export class Company {
  // list of fields ...
  constructor(company: any) {
    if (company != '') {
      this.instantiateEmpty();
    } else {
      this.instantiateWithData();
    }
  }

  private instantiateEmpty() {
    // create empty fields of class
  }

  private instantiateWithData() {
    // create filled fields
  }
}

Or should I create this class with a builder-like approach and just use correct static method depending upon what I need to do with the class: instantiate with data or instantiate with empty fields? 还是应该使用类似于生成器的方法来创建此类,并根据我对类的需要使用正确的静态方法:使用数据实例化还是使用空字段实例化?

Thanks! 谢谢!

Let's start with Object.assign which will make your constructor very slim: 让我们从Object.assign开始,它将使您的构造函数非常苗条:

constructor(company: any) {
    Object.assign(this, company);
}

It will work only if, as you wrote, the company object has the same fields as the class. 如您所写,只有在company对象具有与类相同的字段时,它才有效。

Now, you can also have a different signature to your constructor: 现在,您还可以为构造函数使用不同的签名:

constructor();
constructor(company: any);
constructor(company?: any) {
    if (comapny) {
        Object.assign(this, company);
    } else {
        ....
    }
}

Edit 编辑

In order to initialize all the fields with empty values, I recommend having a constant object which has the same exact fields as the class but with empty fields, then use Object.assign with it, something like: 为了使用空值初始化所有字段,我建议使用一个常量对象,该对象具有与类相同的完全相同的字段,但是具有空字段,然后将Object.assign与之一起使用,例如:

const DEFAULT_VALUES = {
    firmId: 0,
    regNr: "",
    ...
}

class Company {
    constructor();
    constructor(company: any);
    constructor(company?: any) {
        if (comapny) {
            Object.assign(this, company);
        } else {
            Object.assign(this, DEFAULT_VALUES);
        }
    }
}

Or even just: 甚至只是:

class Company {
    constructor(company: any = DEFAULT_VALUES) {
        Object.assign(this, company);
    }
}

EDIT: As pointed out in the comments below - due to the way TS behaves - this solution will not copy over methods of a class to the object. 编辑:正如下面的注释中指出的那样-由于TS的行为方式-该解决方案不会将类的方法复制到该对象。 So it's not really the recommended path to use. 因此,这实际上不是建议的使用路径。


There is no need to use a constructor class here. 此处无需使用构造函数类。

Without a constructor, if you have a JSON which reflects the company structure you want you can simply cast the JSON into the object like so: 如果没有构造函数,那么如果您有一个可以反映公司结构的JSON,则可以将JSON像这样简单地转换为对象:

let company: Company = jsonThatIsACompany;

If you don't have a JSON object to cast, and need an empty object, simply make a new instance of the class: 如果您没有要转换的JSON对象,而需要一个空对象,则只需创建该类的新实例即可:

let company: Company = new Company()

This will be an instance of the object with all empty fields. 这将是具有所有空字段的对象的实例。

With this in mind you do not need a constructor function in your class. 考虑到这一点,您在类中不需要构造函数。 You can just declare the properties as normal. 您可以只将属性声明为正常。

eg: 例如:

export class Company {
  firmId: number;
  regNr: string;
  firmName: string;
  address: string;
  status: string;
  town: string;
  zip: string;
  postAddress: string;
  tel1: string;
  tel2: string;
  fax: string;
  eMail: string;
  homepage: string;
  webshow: string;
  bankcode: string;
  bankaccount: string;
  contact: string;
  addidata: string;
  entryDate: string;
  userId: string;
  infoEMail: string;
  pfId: string;
  pfName: string;
  country: string;
}

The only big difference is you'll need to stop using private on the properties so they can be accessed and changed by whatever is using the object (useful for forms). 唯一的不同是,您需要停止在属性上使用private ,以便可以通过使用该对象的任何对象(对表单有用)进行访问和更改。

As an aside if you were not wanting to use the JSON to populate, you domnt need to define/assign all those properties manually - you can use constructor parameters to do it automatically for you to keep it DRY... 顺便说一句,如果您不想使用JSON进行填充,则必须手动定义/分配所有这些属性-您可以使用构造函数参数自动执行此操作,以使其保持DRY ...

export class Company {

  // declaring constructor parameters with access level 
  // auto defines the class properties for you...
  constructor(private firmId: number,
              private regNr: string,
              private firmName: string,
              private address: string,
              private status: string,
              private town: string,
              private zip: string,
              private postAddress: string,
              private tel1: string,
              private tel2: string,
              private fax: string,
              private eMail: string,
              private homepage: string,
              private webshow: string,
              private bankcode: string,
              private bankaccount: string,
              private contact: string,
              private addidata: string,
              private entryDate: string,
              private userId: string,
              private infoEMail: string,
              private pfId: string,
              private pfName: string,
              private country: string) {
    // also no need to assign them in here...they are automatically assigned
  }

}

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

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