如何在 formGroup 中从打字稿传递自定义字符串,并在模板内的 *ngFor 中读取它的值?

How do I pass down a custom string from typescript, in the formGroup, and read the value of it in *ngFor inside template?

考虑模板中的以下 formArray 摘录:

<div class="p-col-12 controls-div" formArrayName="fields">
    <div
        class="p-grid"
        *ngFor="let item of getFieldControls(); let i = index"
        [formGroupName]="i"
        style="margin-top: 10px;">
        <div class="p-col-8">
            <!-- if string is Text -->
            <input
                *ngIf="string == 'Text'"
                type="text"
                pInputText
                formControlName="control">
            <!-- if string is number -->
            <input
                *ngIf="string == 'Number'"
                type="text"
                pInputText
                formControlName="control">
             <!-- if string is Yes/No -->
             <p-toggleButton
                *ngIf="string == 'Yes/No'" 
                onLabel="Yes" 
                offLabel="No" 
                formControlName="control"></p-toggleButton>
        </div>
        <div class="p-col-2">
        <button
            type="button"
            class="btn btn-danger"
            (click)="onDeleteField(i)">X</button>
        </div>
    </div>                        
</div>

我想从我的 getFieldControls() 方法传递一个字符串并绑定到控件,在 *ngFor 循环中,绑定到正确的“控件类型”(元素)。我的问题是我尝试了 100 种不同的方法来传递这个字符串。我尝试像这样添加数据类型属性:

(<FormArray>this.itemForm.get('fields')).push(
        new FormGroup({
          'control': new FormControl(
            {data-type: 'number', value:variable.name, disabled:true}, [Validators.required])
        })
      );

然后我想在模板中阅读它,就像这样:

*ngIf="item[0].control.data-type == 'text'"

但是编译器报错了。看来只能传值和禁用了。后来我尝试为 formgroup 设置一个值,也没有运气。如果我可以传递一个字符串,我就会知道将哪个控件加载到模板中的 DOM 中。我还尝试从打字稿中直接动态地添加元素,如下所示:

<div [innerHTML]="elementToAdd"></div>

在打字稿中

if (this.type == 'number') {
    elementToAdd += '<input type="number" ...>';
}

当我这样做时,每次添加一个控件时,我都会添加 4 或 8 个控件。在一天结束时,我会得到一个,假设 'dropdown',模板中的值(字符串)和 *ngIf 只有下拉列表,然后绑定到它。

我使用数组根据 id 查找要加载的控件类型。我推送新控件的方法如下所示:

onAddField(id: string) {
    let variable = this.variables.find(i => i.id === id);
    
    if (variable?.control == 'Text') {
      //add an Input
      (<FormArray>this.itemForm.get('fields')).push(
        new FormGroup({
          'control': new FormControl(
            {value:variable.name, disabled:true}, Validators.required)
        })
      );
    }
    if (variable?.control == 'Number') {
      //add an Input
      (<FormArray>this.itemForm.get('fields')).push(
        new FormGroup({
          'control': new FormControl(
            {value:variable.name, disabled:true}, Validators.required)
        })
      );
    }
    //somewhere in the formgroup or formcontrol I want to pass a string so that I can know which form control to load, using *ngIf,in the template.
  }

我这样初始化我的表单:

this.itemForm = new FormGroup({
  fields: new FormArray([])
});

要获得控件,这是我的方法:

getFieldControls() {
  let controls = (this.itemForm.get('fields') as FormArray).controls;
  return controls;
}

你可以这样做。

<div class="p-col-12 controls-div" formArrayName="fields">
    <div
        class="p-grid"
        *ngFor="let item of getFieldControls(); let i = index"
        [formGroupName]="i"
        style="margin-top: 10px;">
          <div class="p-col-8">
            <!-- if string is Text -->
            <input
                *ngIf="typeList[index] == 'Text'"
                type="text"
                pInputText
                formControlName="control">
            <!-- if string is number -->
            <input
                *ngIf="typeList[index] == 'Number'"
                type="text"
                pInputText
                formControlName="control">
             <!-- if string is Yes/No -->
             <p-toggleButton
                *ngIf="typeList[index] == 'Yes/No'" 
                onLabel="Yes" 
                offLabel="No" 
                formControlName="control"></p-toggleButton>
        </div>
        <div class="p-col-2">
        <button
            type="button"
            class="btn btn-danger"
            (click)="onDeleteField(i)">X</button>
        </div>
    </div>                        
</div>

onAddField() 中你可以这样做。因为我认为 variable 在这里有点相关。

typeList: stringp[] = [];
onAddField(id: string) {
    let variable = this.variables.find(i => i.id === id);
    this.typeList.push(variable?.control)
    
    if (variable?.control == 'Text') {
      //add an Input
      (<FormArray>this.itemForm.get('fields')).push(
        new FormGroup({
          'control': new FormControl(
            {value:variable.name, disabled:true}, Validators.required)
        })
      );
    }
    if (variable?.control == 'Number') {
      //add an Input
      (<FormArray>this.itemForm.get('fields')).push(
        new FormGroup({
          'control': new FormControl(
            {value:variable.name, disabled:true}, Validators.required)
        })
      );
    }
    //somewhere in the formgroup or formcontrol I want to pass a string so that I can know which form control to load, using *ngIf,in the template.
  }