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

Angular TypeScript:带有构造函数的类,该构造函数根据传入参数调用方法,angular,typescript,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: strin

我有一个常规的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;
  }
}
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
  }
}
这个构造器显然非常胖,我正在考虑重构到构造器模式,但现在它是这样的

这个类是用一个JSON响应实例化的,它具有完全相同的字段结构

当我需要用空值实例化这个类以使角度形式验证正常工作时,问题就出现了

我怎样才能做到这一点?我是否可以创建一个构造函数,根据构造函数参数调用此类的方法,如下所示:

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;
  }
}
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
  }
}
或者我应该使用类似于构建器的方法创建这个类,并根据需要对该类执行的操作使用正确的静态方法:使用数据实例化还是使用空字段实例化


谢谢

EDIT:正如下面评论中所指出的,由于TS的行为方式,此解决方案不会将类的方法复制到对象上。所以这并不是推荐使用的路径


这里不需要使用构造函数类

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

let company: Company = jsonThatIsACompany;
如果您没有要强制转换的JSON对象,并且需要一个空对象,只需创建该类的新实例:

let company: Company = new Company()
这将是包含所有空字段的对象实例

记住这一点,类中不需要构造函数。您可以将属性声明为普通属性

e、 g:


唯一的区别是您需要停止在属性上使用
private
,以便使用对象的任何人都可以访问和更改这些属性(对表单很有用)。

编辑:正如下面的注释所指出的,由于TS的行为方式,此解决方案不会将类的方法复制到对象上。所以这并不是推荐使用的路径


这里不需要使用构造函数类

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

let company: Company = jsonThatIsACompany;
如果您没有要强制转换的JSON对象,并且需要一个空对象,只需创建该类的新实例:

let company: Company = new Company()
这将是包含所有空字段的对象实例

记住这一点,类中不需要构造函数。您可以将属性声明为普通属性

e、 g:

唯一的区别是您需要停止在属性上使用
private
,以便使用对象的任何人都可以访问和更改这些属性(对表单很有用)。

让我们从这一点开始,它将使您的构造函数非常精简:

constructor(company: any) {
    Object.assign(this, company);
}
正如您所写,只有当
公司
对象具有与类相同的字段时,它才会工作

现在,您还可以对构造函数使用不同的签名:

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

编辑 为了使用空值初始化所有字段,我建议使用一个常量对象,该对象与类具有相同的字段,但具有空字段,然后使用
object。使用它分配
,类似于:

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);
    }
}
让我们从使您的构造函数非常纤细的方面开始:

constructor(company: any) {
    Object.assign(this, company);
}
正如您所写,只有当
公司
对象具有与类相同的字段时,它才会工作

现在,您还可以对构造函数使用不同的签名:

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

编辑 为了使用空值初始化所有字段,我建议使用一个常量对象,该对象与类具有相同的字段,但具有空字段,然后使用
object。使用它分配
,类似于:

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

另外,如果您不想使用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
  }

}

另外,如果您不想使用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
  }

}

这是一个错误。这样就不会得到类的实例,只有一个具有相同字段的js对象。但如果类有方法,这个对象就不会有方法。有趣的是,我不知道这一点——TS的一个主要烦恼就是它是如何工作的。诚然,在这种情况下没有涉及到任何方法,但仍然值得遵循您的答案。。难道没有允许使用方法的单行强制转换吗?可能将
用作公司
?不,您需要实例化该类(使用
new
关键字)。编译器不会抱怨的原因是。所以,如果你在使用你的方法,那么永远不要使用类,只使用接口或类型别名,这样你就不会意外地向它添加方法(这将导致错误),而且你的js代码也不会有多余的未使用的代码。这是一个错误。这样就不会得到类的实例,只有一个具有相同字段的js对象。但如果类有方法,这个对象就不会有方法。有趣的是,我不知道这一点——TS的一个主要烦恼就是它是如何工作的。诚然,在这种情况下没有涉及到任何方法,但仍然值得遵循您的答案。。难道没有允许使用方法的单行强制转换吗?可能将
用作公司
?不,您需要实例化该类(使用
new
关键字)。编译器不会抱怨的原因是。因此,如果您正在使用方法,那么永远不要使用类,只使用接口或类型别名,这样您就不会意外地向其中添加方法(这将导致错误),而且您的js代码也不会有多余的未使用的代码。谢谢!看起来是个好办法!在
else
部分中,可以调用