简体   繁体   中英

Angular Data binding repeated

I created a form. Then I added a link to add a section like previous

图片1

when clicked add another address, it displayed address 2 form

图片2

Then I clicked the first input field, the validations errors are displayed in 2nd form also

图3

how to fix this?

app.component.html

<label for="line1">STREET 1</label>
   <input id="line1" type="text" formControlName="line1" required/>
   <error-component
      [control]="formAddress.controls.line1">
   </error-component>

app.component.ts

formAddress = this.formBuilder.group({
    line1: ["", Validators.required],
    line2: '',
    postalCode: ["", Validators.required],
  });

Your problem is that you only are repeating the "same" FormGroup. (check your code to see that you have an unique formGroup. Remember that if we have an array and use some like:

  formGrup="..."
  array=[this.formGroup]
  //in any place
  array.push(this.formGroup)

  //the two elements of the array is the same formGroup!!!

One Solution : The idea is use a FormArray of FormGroups (another one it's use an Array of FormGroup)

When we have an array of FormGroups we create a function that return a FormGroup

createAddressGroup()
{
  return new FormGroup({
    line1:new FormControl("", Validators.required),
    line2: new FormControl(''),
    postalCode: new FormControl("", Validators.required),
  })
}

And we create de he formArray, and create a function to add a new FormGroup to the array and another one to delete

formArray=new FormArray([this.createAddressGroup()])

addAddress()
{
   this.formArray.push(this.createAddressGroup());
}
removeAddress(index:number)
{
   this.formArray.removeAt(index);
}

When mannage a FormArray not inside a FormGroup we need create a function that return the formGroup

getAddress(index:number)
{
   return this.formArray.at(index) as FormGroup
}

Well, it's all ready to create the.html

<!--see that iterate over formArray.controls, and we indicate
    the formGroup using formGroup]="getAddress(i)"-->
<fieldset *ngFor="let group of formArray.controls;let i=index"
     [formGroup]="getAddress(i)">
     <legend>{{'Address '+(i+1)}}</leyend>
     <div>
        <label for="email">Street 1</label>
        <input id="email" formControlName="line1" />
        <div class="invalid-feedback">
            * Required
        </div>
    </div>
     <div>
        <label for="email">Street 2</label>
        <input id="email" formControlName="line2" />
    </div>
     <div>
        <label for="email">Country</label>
        <input id="email" formControlName="postalCode" />
        <div class="invalid-feedback">
            * Required
        </div>
    </div>
</fieldset>

Where I'm using the.css showed in this SO and this stackblitz

.invalid-feedback
{
   display:none
}
.ng-invalid.ng-touched ~ .invalid-feedback
{
  display: block;
}

You have to use the index from "over array iteration" to build "for" and "id" attributes of each field. Like

<ng-container formArrayName="files">
    ...
    <ng-container [formGroupName]="i">

            <label [for]="'file_name_' + i.toString()">
              {{ "contents.practice.fields.files.name" | translate }}
            </label>
            <div class="form-control">
              <input
                pInputText
                [id]="'file_name_' + i.toString()"
                type="text"
                formControlName="name"
                autocomplete="off"
                class="flex-auto"
              />
            </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM