Angular2 One-way binding form doesn't get clea

2019-03-01 09:07发布

I have a form where inputs are bound to object one-way.

<input type="text" name="lastName" #lastName="ngModel" [ngModel]="selectedPers.lastName" required minlength="2">

When saving form I read form data and send it to server, then update my model with dummy/empty data to clear it out.

this.peopleListObservable.push(newPersonFormData).then(a => {
        this.clearPers();
      })


  clearPers() {    
    this.selectedPers = this.dummyPers;
    this.isPersAdd = true;
  }

This clear-out method is separate and works when I call it from a button click, but it doesn't work/clear form if I call it after sending my data to server in my save promise then method. Any ideas why I experience such behavior and what shall I do to clear out my form?

EDIT: I've changed clearPers function like so with hope to reload the page:

  clearPers() {    
    console.log('Inside clearPers function');
   this.router.navigate(['/person/' + this.key]);
  }

guess what, console log is printed but router navigation didn't happen.

What am I missing?

EDIT 2: Thanks @FabioAntunes for reminding me that router idea wouldn't work anyways.

EDIT 3: Question is asked for a project with Angular 2 RC4 release. Read below my answer for what happened later and is supposed to happen in final release of Angular2.

3条回答
来,给爷笑一个
2楼-- · 2019-03-01 09:28

After playing with method described in Fabio's answer I've decided to go back for my initial idea, using route parameters to refresh my component, which in term refreshes my forms. Using *ngIf to recreate form seems logical since we don't have at the moment (RC4 of Angular2) a natural way of reseting forms, however for some reason re-creation after timeout caused to refresh whole page in my component. I didn't want to spend more time to fix a solution that didn't feel so natural.

While looking for other answers in Stackoverflow, I ran into Resetting a form in Angular 2 after submit.

Answers from @angular-university and @jp-att reveals that RC5 has a fix, form.reset() method. Unfortunately I can't port my project to RC5 right away now.

So I was back to my initial idea (till I port my app to RC5/final), using routing to refresh component.

First I've tried using a query parameter,

this.router.navigate(['person/' + this.idKey],{ queryParams: { timestamp: nowTimeNumber}});

That doesn't help, probably because of the same reason it wouldn't help using a route parameter that is not bound to any model in your component: Angular's change detection does not trigger a refresh of your component if that change doesn't affect anything (at least this is my guess). Also query parameters are sticky to url, very ugly just for a refresh trick.

So I did this: I've created a new child route

{ path: 'person/:personid', component: PersonEditComponent},
{ path: 'person/:personid/:timestamp', component: PersonEditComponent}

Read(observe) timestamp, and go back and forth when I need to clear form data:

  clearPersonDataRouted(){
    let newTime = moment().unix();
    if(this.timeRouteParam)
    this.router.navigate(['person/'+ this.idKey]);
    else
    this.router.navigate(['person/'+ this.idKey + '/' + newTime]);
  }
查看更多
狗以群分
3楼-- · 2019-03-01 09:31

Angular2 Forms don't have the reset option yet, if you read the documentation for the Forms, they give you a temporary fix.

Upon reflection, we realize that Angular cannot distinguish between replacing the entire hero and clearing the name property programmatically. Angular makes no assumptions and leaves the control in its current, dirty state.

Just add an active property to your component's class, then on your form add an ngIf:

<form *ngIf="active">

Then on your function:

clearPers() {    
  this.selectedPers = this.dummyPers;
  this.isPersAdd = true;
  this.active = false;
  setTimeout(() => this.active = true, 0);
}

The setTimeout bit is the temporary fix:

This is a temporary workaround while we await a proper form reset feature.

查看更多
一纸荒年 Trace。
4楼-- · 2019-03-01 09:35

I think your syntax is a little off. You are not doing one way or two way data binding with your input syntax. Try this to do two way data binding instead:

<input type="text" name="lastName" [(ngModel)]="selectedPers.lastName" required minlength="2">

Also, you don't need this: #lastName="ngModel"

If you want to do one way data binding (which you can't use to clear your control) use this:

<input type="text" name="lastName" [value]="selectedPers.lastName" required minlength="2">
查看更多
登录 后发表回答