如何有条件地更改Angular中对象的静态类型?

时间:2019-07-25 14:12:06

标签: angular typescript

我正试图创建一个在线商店,并且很难实施一个灵活的表格系统,理想情况下,该系统应根据我添加到商店中的商品类型进行更改。 例如,当选择“服装”类别时,创建的对象的静态类型会更改,并且表单会自动变形并删除/创建所有必要的输入字段。

interface Item {
  id: string;
  title: string;
  category: string;
  price: number;
}

interface ClothingItem extends Item {
  size: string;
}

interface MonitorItem extends Item {
  resolution: string;
}
@Component({…})
export class ItemCreateComponent {
  item: Item;
  form = this.fb.group({
    category: [''],
    title: [''],
    price: [''],
  });
  constructor(private fb: FormBuilder) { }

我希望发生的事情是,当用户在表单中选择“服装”类别时,item的类型会更改为ClothingItem,而form属性会添加缺少的表单控件。

提出这个问题真的很困难,我真正希望您至少清楚一点。

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作(这只是一个主意,我尚未对其进行测试):

@Component({…})
export class ItemCreateComponent {
  formFields: string[] = [];
  form: FormGroup = new FormGroup();

  item: Item;

  constructor(private fb: FormBuilder) {}

  buildForm(item: Item) {
    this.formFields = [];

    const obj = {};
    const keys = Object.keys(item).sort();
    for(const key of keys) {
     obj[key] = [''];
    }

    // The setTimeout is just to give time to angular change 
    // detection to destroy the form already present on the dom 
    // before switching to the new form shape. Otherwise, 
    // you could get an error for having, in the form template,  
    // HTML form elements different from the ones currently set  
    // on this.form object 
    setTimeout(() => {
      this.form = this.fb.group(obj);

      this.formFields = keys;
    }, 300);
  }

和模板中

<form [formGroup]="form">
    <input *ngFor="let field of formFields" 
           [formControlName]="field">
</form>

答案 1 :(得分:0)

如果您希望项目可以互换,则项目的类型应为any,而不是Item,因为这只会Item类型的对象。

如果您以后要检查商品的类型是否正确,请使用

item instanceof yourDerivedItem

const result = (item: any): item is yourDerivedItem => { return true }