Pablo Ivan
Pablo Ivan

Reputation: 280

Bind ngModel value across components

Say you have about.component.ts with the following:

import { Component } from '@angular/core';

@Component({
  selector: 'about-section',
  template: `
    <input [(ngModel)]="name" placeholder="First Name">
    <p>{{name || 'user'}}</p>
  ` 
})

export class AboutComponent {

}

Then you have notes.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'notes-section',
  template: `
    <p>{{name || 'user'}}</p>
  ` 
})

export class NotesComponent {

}

Both files are components of app.component.ts:

import { Component } from '@angular/core';

import { AboutComponent } from './about.component';
import { NotesComponent } from './notes.component';

@Component({
  selector: 'my-app',
  template: `
  <about-section></about-section>
  <notes-section></notes-section>
  `,
  directives: [AboutComponent, NotesComponent]
})

export class AppComponent { }

My question is, how would you bind the ngModel 'name' property from about.component.ts to notes.component.ts so whenever you write your name, the change is reflected both in the notes component and the about component?

Upvotes: 0

Views: 1463

Answers (1)

yurzui
yurzui

Reputation: 214077

One way to do it is using EventEmitter:

@Component({
  selector: 'about-section',
  template: `
    <input [ngModel]="name" (ngModelChange)="name = $event; modelChanged.emit($event)">
    <p>{{name || 'user'}}</p>
  ` 
})
export class AboutComponent {
  @Output() modelChanged = new EventEmitter();
}

@Component({
  selector: 'notes-section',
  template: `<p>{{name || 'user'}}</p>` 
})
export class NotesComponent {}

@Component({
  selector: 'my-app',
  template: `
   <about-section (modelChanged)="notes.name = $event"></about-section>
   <notes-section #notes></notes-section>`,
  directives: [AboutComponent, NotesComponent]
})
export class AppComponent { }

Check demo plunker here

Firstly i extracted banana in a box [(ngModel)]="name" (https://angular.io/docs/ts/latest/guide/template-syntax.html#!#two-way-binding-with-ngmodel) to emit EventEmitter event from the component containing ngModel.

<input [ngModel]="name" (ngModelChange)="name = $event; modelChanged.emit($event)">

Then i just subscribed to this event in parent component:

<about-section (modelChanged)="notes.name = $event"></about-section>

but before it i kept reference on other component to be able to change name as shown in the above code notes.name = $event where $event is representing "payload" of the raised event (input value in this case).

<notes-section #notes></notes-section>

Upvotes: 4

Related Questions