Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Angular 2 ngModel directive to use observables

Angular 2 ngModel directive works with variables and functions like

<input [ngModel]="myVar" (ngModelChange)="myFunc($event)" />

Instead of variables and functions, I would like to use BehaviorSubjects instead

<input [ngModel]="mySubject | async" (ngModelChange)="mySubject.next($event)" />

Is there a safe way to extend ngModel or use some kind of macro to reduce repetition in my templates?

<input [myNewNgModel]="mySubject" />
like image 386
nwarp Avatar asked Sep 06 '25 06:09

nwarp


2 Answers

I came up with a similar approached to @Adbel. Not sure about the inner implications of this, but it will be awesome to have some feedback. Stackbliz code

Your.component.ts

export class AppComponent  {
  email = new BehaviorSubject("UnwrappedMe 😱");

  emailHandler(input) {
    this.email.next(input);
  }
}

Your.component.html

 <form class="mx-3">
     <input [ngModel]="email | async" 
            (ngModelChange)="emailHandler($event)" 
            name="email" type="email" 
            id="email" placeholder="Enter email">
 </form>

 <p class="mx-3"> {{ email | async }} </p>

A little variation in case you need to get a ref to your input value and you do not want to make a second subscription (use template vars).

Your.component.html

 <form class="mx-3">
     <input [ngModel]="email | async" #emailref
            (ngModelChange)="emailHandler($event)" 
            name="email" type="email" 
            id="email" placeholder="Enter email">
 </form>

 <p class="mx-3"> {{ emailref.value }} </p>
like image 142
Luillyfe Avatar answered Sep 07 '25 19:09

Luillyfe


I don't know why you wouldn't just use reactive forms, but this was a fun puzzle. I created a directive that will alter the model value to the BehaviorSubject's value. And any changes will call .next on the BehaviorSubject for you.

Usage will look like this

<input type="text" [ngModel]="ngModelValue" appRxModel> 

Here is the stackblitz, enjoy

like image 21
realappie Avatar answered Sep 07 '25 19:09

realappie