Home > Software design >  Angular ngModel one-way binding
Angular ngModel one-way binding

Time:02-22

I have select control with [ngModel] binding. (ngModelChange) handler has a custom check that must discard certain values. I can't just put [disabled] on my input because I need to allow user to try to select another value and show an error if it's not valid. I have the following component:

<select [ngModel]="value" (ngModelChange)="onChange($event)">
  <option [ngValue]="1">Test 1</option>
  <option [ngValue]="2">Test 2</option>
</select>
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  value = 1;

  onChange(value: number) {
    if (false) { // custom business logic
      this.value = value;
    }
  }
}

I expect that when user attempts to select value 2 it will be reverted back to value 1 because model hasn't changed. But it's changed regardless of [ngModel] binding. Why it's happening and is there a workaround that doesn't involve usage of formControl instead of ngModel?

CodePudding user response:

Not sure if this is what you're looking for but you can use a local template variable #select and assign the onChange method to select.value and control the value based on your conditions.
Something like that: Stackblitz

CodePudding user response:

you need change also the "DOM"(*), see how you pass a template reference variable in the function. In the case of a select you need change the selectedIndex (in a normal input you change the value

<select #select [ngModel]="value" (ngModelChange)="onChange($event,select)">
  <option [ngValue]="1">Test 1</option>
  <option [ngValue]="2">Test 2</option>
</select>

  onChange(value: number,select:HTMLSelectElement) {
    if (window.confirm('¿Are you sure?')) { // custom business logic
      this.value = value;
    }
    else
    {
      select.selectedIndex=this.value==1?0:1
    }
  }

NOTE: In the example the "logic" it's a simple confirm, and the way to get the selectedIndex is a bit "hardcode". I imagine you has an array with the possibles values, find the index in the array and give this index

(*)Angular check the change of the model, but the model don't change, so, has no way to show the "same value"

  • Related