Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

javascript - Using ngFor with ngModel dynamic data wrong behaviour

I have complex and probably rookie bug in logic of my application, so I'll try to give comprehensive amount of information.

I have registration form binded to my data model. Phone number fields can be added by user during registration and saved as array.

My model:

export class RegistrationFormModel {
  //
  //
    Phones: Array<{Phone: string;}>;
  //
  //
}

And representation of this part of form

     <ion-item *ngFor="let Phone of regModel.Phones; let i = index">

        <ion-label floating>Phone number*</ion-label>
        <ion-input type="tel" required [(ngModel)]="regModel.Phones[i].Phone" name="Phone" #Phone="ngModel"
                   pattern="d{10}"></ion-input>
        <ion-icon *ngIf="i==0" name="ios-add-circle-outline" item-right no-padding
                  (click)="addPhone()"></ion-icon>
        <ion-icon *ngIf="i!=0" name="ios-remove-circle-outline" item-right no-padding
                  (click)="removePhone(i)"></ion-icon>

     </ion-item>

My methods for adding and removing phones. I added logs and incremental index for debug purposes:

debugIndex = 0;
 \
 \
  addPhone() {
    console.log('phones before add: ' + JSON.stringify(this.regModel.Phones));
    this.regModel.Phones.splice((this.regModel.Phones.length), 0, {Phone: '' + this.debugIndex++});
    console.log('phones after add: ' + JSON.stringify(this.regModel.Phones));
  }

  removePhone(i: number) {
    console.log('phones before delete: ' + JSON.stringify(this.regModel.Phones));
    this.regModel.Phones.splice(i, 1);
    console.log('phones after delete: ' + JSON.stringify(this.regModel.Phones));
  }

And from this part strange things happen. According to logs data writes in my model properly but in UI last element replaces everything in input fields. But after removing one of the phones displayed phones for this moment seems like represent last state of UI.

enter image description here

My logs captured during recording:

 "phones before add: [{"Phone":"123456789"}]", 
  "phones after add: [{"Phone":"123456789"},{"Phone":"0"}]", 
  "phones before add: [{"Phone":"123456789"},{"Phone":"4567890"}]", 
  "phones after add: [{"Phone":"123456789"},{"Phone":"4567890"},{"Phone":"1"}]", 
  "phones before delete: [{"Phone":"123456789"},{"Phone":"4567890"},{"Phone":"1"}]", 
  "phones after delete: [{"Phone":"123456789"},{"Phone":"4567890"}]", 
  "phones before add: [{"Phone":"123456789"},{"Phone":"4567890"}]", 
  "phones after add: [{"Phone":"123456789"},{"Phone":"4567890"},{"Phone":"2"}]", 
  "phones before add: [{"Phone":"123456"},{"Phone":"4567890"},{"Phone":"2"}]", 
  "phones after add: [{"Phone":"123456"},{"Phone":"4567890"},{"Phone":"2"},{"Phone":"3"}]", 
  "phones before add: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"2"},{"Phone":"3"}]", 
  "phones after add: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"2"},{"Phone":"3"},{"Phone":"4"}]", 
  "phones before delete: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"2"},{"Phone":"3"},{"Phone":"4"}]"
  "phones after delete: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"2"},{"Phone":"4"}]", 
  "phones before add: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"47890"},{"Phone":"4"}]", 
  "phones after add: [{"Phone":"123456"},{"Phone":"456789"},{"Phone":"47890"},{"Phone":"4"},{"Phone":"5"}]"

Any help appreciated and thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Adding [ngModelOptions]="{standalone: true}" to your input should fix the problem:

<ion-input type="tel" required [(ngModel)]="regModel.Phones[i].Phone" 
[ngModelOptions]="{standalone: true} #Phone="ngModel" pattern="d{10}">
</ion-input>

For every input with NgModel directive, FormControl will be created and it will be added to FormGroup, but when you add standalone: true, the fields won't be added to the FormGroup and this problem should be fixed. You should also remove name attribute from your input because only one of those is needed when using template driven forms. (name or standalone: true)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...