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

时间:2017-08-30 11:04:37

标签: angular typescript

我有一个常规的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;
  }
}

这个构造函数显然非常胖,我正在考虑重构构建器模式,但现在就是这样。

此类使用JSON响应进行实例化,该响应具有完全相同的字段结构。

当我需要使用空值实例化此类以使Angular表单验证正常工作时,会出现问题。

我怎样才能实现这一目标?我可以根据构造函数参数创建一个调用此类方法的构造函数,如下所示:

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

或者我应该使用类似构建器的方法创建此类,并根据我需要对类执行的操作使用正确的静态方法:使用数据实例化或使用空字段实例化?

谢谢!

3 个答案:

答案 0 :(得分:4)

让我们从Object.assign开始,这将使你的构造函数变得非常苗条:

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

只有当你写的company对象与该字段具有相同的字段时,它才会起作用。

现在,您还可以为构造函数添加不同的签名:

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

修改

为了使用空值初始化所有字段,我建议使用一个常量对象,该字段与类具有相同的确切字段,但是使用空字段,然后使用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);
        }
    }
}

甚至只是:

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

答案 1 :(得分:0)

编辑:正如下面的评论所指出的 - 由于TS的行为方式 - 这个解决方案将类的方法复制到对象。所以它并不是推荐使用的路径。

此处无需使用构造函数类。

如果没有构造函数,如果你有一个反映你想要的公司结构的JSON,你可以简单地将JSON转换为对象,如下所示:

let company: Company = jsonThatIsACompany;

如果您没有要投射的JSON对象,并且需要一个空对象,只需创建该类的新实例:

let company: Company = new Company()

这将是具有所有空字段的对象的实例。

考虑到这一点,您不需要在类中使用构造函数。您可以正常声明属性。

e.g:

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

唯一的区别在于您需要停止在属性上使用private,以便可以通过使用该对象的任何内容访问和更改它们(对表单有用)。

答案 2 :(得分:0)

另外如果您不想使用JSON填充,您需要手动定义/分配所有这些属性 - 您可以使用构造函数参数自动执行它以使其保持干燥...

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
  }

}