简体   繁体   中英

Angular 2+ unbind properties in ngIf

I have a form with a datepicker. On certain days of data entry, additional fields will be shown. For instance

<div *ngIf="ticketDate.getDay() === 0"

Inside of this div, I am binding to some optional properties on my model. However, if the user changes the date picker to a different date after entering data, the contents of the div are no longer visible but the properties remain set on my model.

Is there an idiomatic way to unbind properties that are bound inside an *ngIf when it is false?

You could set a template reference variable #myDiv on the div element:

<div #myDiv *ngIf="ticketDate.getDay() === 0">

and monitor the presence of the element with ViewChildren and the QueryList.changes event. The model properties could be reset when the div is removed from the DOM:

@ViewChildren("myDiv") myDivList: QueryList<ElementRef>;

value1: string;
value2: string;
value3: string;

constructor(private changeDetectorRef: ChangeDetectorRef) { }

ngAfterViewInit() {
  this.myDivList.changes.subscribe((list) => {
    if (!list.length) {
      this.value1 = undefined;
      this.value2 = undefined;
      this.value3 = undefined;
      this.changeDetectorRef.detectChanges();
    }
  });
}

See this stackblitz for a demo. The method ChangeDetectorRef.detectChanges is called to prevent an Angular exception.

You say that you are using a form, apparently a template driven form if you are using ngModel . You could just not use [(ngModel)] and instead use ngModel . Then there is no need to reset values. If the part of template is not visible, it will not be included in the form at all. If that is a suitable option, I suggest the following (demo is modified version of ConnorsFan's stackblitz):

<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
  <div *ngIf="ticketDate.getDay() === 0">
    Value1: <input ngModel name="value1">
    Value2: <input ngModel name="value2">
  </div>
  <button type="submit">Submit</button>
</form>

Name (all) the form fields like you want, and in the structure you want, so that when you submit your form, the form object corresponds to the model you want. So the above form values submitted would be (if condition is true):

{
  "value1": "some value",
  "value2": "some value"
}

DEMO: https://stackblitz.com/edit/angular-sxwbsd?file=src%2Fapp%2Fapp.component.html

PS: if you need reference to the form in your ts file at some point you can use ViewChild as seen in the demo.

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