How to “walk” inside two arrays using the same *ngFor?

后端 未结 3 1480
北荒
北荒 2020-12-22 07:29

Basically I have two arrays, and I would like to store their values at the same time using a *ngFor, I did something like this just to show what I would expect:

相关标签:
3条回答
  • 2020-12-22 08:10

    I think your issue is here:

    addAlternativeField() {
            this.alternativeFields.push(this.fbuilder.control(''));
            this.alternativeFieldsValues.push(this.fbuilder.control(''));
          }
    

    You are patching the arrays in direct reference to this. Isn't it supposed to be

    this.form.get('alternativeFields').push(this.fbuilder.control(''))
    

    Or do you have an additional getter?

    0 讨论(0)
  • 2020-12-22 08:13

    I believe your mistake is having 2 arrays of controls instead of one array of groups:

    alternativeFieldsAndValues: this.fbuilder.array([]),
    

    and then:

     get alternativeFieldsAndValues() {
       return this.form.get('alternativeFieldsAndValues') as FormArray;
     }
    
      addAlternativeFieldAndValue() {
        this.alternativeFieldsAndValues.push(this.fbuilder.group({
          titulo: '',
          conteudo: ''
        }));
      }
    
      removeAlternativeFieldAndValue(index: any) {
        this.alternativeFieldsAndValues.removeAt(index);
      }
    

    make sure to refactor all names properly then do this:

     <div formArrayName="alternativeFieldsAndValues" *ngFor="let field of alternativeFieldsAndValues.controls; let i = index">
        <div [formGroupName]="i">
          <mat-form-field appearance="standard" class="fullSize">
            <mat-label>Titulo</mat-label>
            <input formControlName="titulo" type="text" matInput autocomplete="off"
              placeholder="Titulo">
          </mat-form-field>
          <mat-form-field appearance="standard" class="fullSize">
            <mat-label>Conteúdo</mat-label>
            <input formControlName="conteudo" type="text" matInput autocomplete="off"
              placeholder="Conteúdo deste campo">
          </mat-form-field>
        </div>
      </div>
    

    that being said, you could accomplish exactly what you asked like this:

       <div *ngFor="let field of alternativeFields.controls; let i = index">
          <mat-form-field formArrayName="alternativeFields" appearance="standard" class="fullSize">
            <mat-label>Titulo</mat-label>
            <input [formControlName]="i" type="text" matInput autocomplete="off"
              placeholder="Titulo">
          </mat-form-field>
          <mat-form-field formArrayName="alternativeFieldsValues" appearance="standard" class="fullSize">
            <mat-label>Conteúdo</mat-label>
            <input [formControlName]="i" type="text" matInput autocomplete="off"
              placeholder="Conteúdo deste campo">
          </mat-form-field>
        </div>
    

    but this does require the two lists are ALWAYS of the same length.

    0 讨论(0)
  • 2020-12-22 08:30

    Matheus, a formArray can be a FormArray of FormControls or a FormArrays of FormGroup (*)

        form=new FormGroup({
           arrayOfControls=new FormArray([])
        })
        pushArrayOfControls()
        {
           this.form.get('arrayOfControls').push(new FormControl())
        }
        //or using FormBuilder
      this.form = this.fb.group(
          {
            arrayOfControls: this.fb.array([])
          }
      )
      pushArrayOfControls() {
        (this.form.get('arrayOfControls') as FormArray).push(
          this.fb.control('')
        )
      }
    

    A formArray of FormGroup:

    form=new FormGroup({
       arrayOfFormGroup=new FormArray([])
    })
    pushArrayOfFormGroup()
    {
       this.form.get('arrayOfControls').push(
         new FormGroup({
             prop1:new FormControl()
             prop2:new FormControl()
         }))
    }
    //or using FormBuilder
    form=this.fb.group({
       arrayOfFormGroup=this.fb.array([])
    })
    pushArrayOfFormGroup()
    {
       this.form.get('arrayOfControls').push(this.fb.group({
          prop1:'',
          prop2:''
       })
    }
    

    One store an array of values ['a','b','c'], the other store an array of object [{prop1:'a',prop2:'aa'},{prop1:'a',prop2:'aa'}]

    To manage it's use different ways. The clasic for a FormArray of controls is

    <div [formGroup]="form">
      <div formArrayName="arrayOfControls">
        <div *ngFor="let control of form.get('arrayOfControls').controls;let i=index">
          <!---use [formControlName]="i"-->
          <input [formControlName]="i"/>
        </div>
      </div>
    </div>
    

    But remember, our formArray is a formArray of control, so we can do something like

    <div [formGroup]="form">
      <div formArrayName="arrayOfControls">
        <div *ngFor="let control of form.get('arrayOfControls').controls;">
          <!---use [formControl]="control", the variable of the *ngFor-->
          <input [formControl]="control"/>
        </div>
      </div>
    </div>
    

    And we can make something so "bizarro" like

    <div [formGroup]="form">
      <div formArrayName="arrayOfControls">
        <div *ngFor="let control of form.get('arrayOfControls').controls;let i=index">
          <input [formControl]="form.get('arrayOfControls').at(i)"/>
        </div>
      </div>
    </div>
    

    A formArray of formGroup, we can the way clasic

    <div [formGroup]="form">
      <div formArrayName="arrayOfFormGroup">
        <!--see that we use [formGroupName]-->
        <div *ngFor="let control of form.get('arrayOfFormGroup').controls;
               let i=index" [formGroupName]="i">
          <input formControlName="prop1"/>
          <input formControlName="prop2"/>
        </div>
      </div>
    </div>
    

    Well, nobody say that we can not do, remember that is a formArray of controls, so, for.get('arrayOfGroup').controls is a FormGroup

    <div [formGroup]="form">
      <div formArrayName="arrayOfControls">
         <!--here I used "formGroup"-->
        <div *ngFor="let group of form.get('arrayOfControls').controls"
            [formGroup]="group">
          <input formControlName="prop1"/>
          <input formControlName="prop2"/>
        </div>
      </div>
    </div>
    

    even something so "bizarro"

    <div [formGroup]="form">
      <div formArrayName="arrayOfControls">
        <div *ngFor="let group of form.get('arrayOfControls').controls;let i=index" >
           <!--I used directily [formControl]-->
          <input [formControl]="form.get('arrayOfControls').at(i).get('prop1')"/>
          <input [formControl]="form.get('arrayOfControls').at(i).get('prop2')"/>
        </div>
      </div>
    </div>
    

    Well, now, the question is: What do you want? a formArray of FormGroup or an formArray of FormControls, what way of referered to the FormControls do you wants, using formControl, using formControlName, using formGroup?

    NOTE: it's usefull use a getter to referered to our formArray

    get myArray()
    {
        return this.form.get('arrayOfControls') as FormArray
    }
    

    and replace in the .html this "ugly" form.get(....)

    (*)Really a FormArray don't need create into a formGroup, they "lives" outside

    0 讨论(0)
提交回复
热议问题