I made a simple UI which consist two components (parent and child).
What the UI does is that when I type some stuff in the input box of the Child component. The value will change using ngModel.
The child component works fine that way.
// Child Component @Component({ selector: 'child', template: ` <p>{{sharedVar}}</p> <input [(ngModel)]="sharedVar"> ` }) export class ChildComponent { sharedVar: string; }
Now I have a parent component which I intend to use the same value as Child Component.
I added the Child Component into the Parent template, and use dependency injection to call Child Component's sharedVar
.
// Parent Component @Component({ selector: 'parent', template: ` <h1>{{sharedVar}}</h1> <child></child> `, directives: [ChildComponent], providers: [ChildCompnent] }) export class ParentComponent { sharedVar: string; constructor(child: ChildComponent) { this.sharedVar = child.sharedVar; } }
The problem is as I'm typing in the input box, the value in <p>
changes automatically while the value in parent component's <h1>
do not change.
We can use the [(x)]
syntax in the parent template to achieve two-way databinding with the child. If we create an Output property with the name xChange
, Angular will automatically update the parent property. We do need to emit()
an event whenever the child changes the value however:
import {Component, EventEmitter, Input, Output} from 'angular2/core' @Component({ selector: 'child', template: ` <p>Child sharedVar: {{sharedVar}}</p> <input [ngModel]="sharedVar" (ngModelChange)="change($event)"> ` }) export class ChildComponent { @Input() sharedVar: string; @Output() sharedVarChange = new EventEmitter(); change(newValue) { console.log('newvalue', newValue) this.sharedVar = newValue; this.sharedVarChange.emit(newValue); } } @Component({ selector: 'parent', template: ` <div>Parent sharedVarParent: {{sharedVarParent}}</div> <child [(sharedVar)]="sharedVarParent"></child> `, directives: [ChildComponent] }) export class ParentComponent { sharedVarParent ='hello'; constructor() { console.clear(); } }
Plunker
I used sharedVarParent
in the ParentComponent just to demonstrate that the names don't have to be the same in the parent and child.
You could set up event emitter communication (outputs
) from child to parent. For example like this:
@Component({ selector: 'child', template: ` <p>Child: {{sharedVar}}</p> <input [(ngModel)]="sharedVar" (ngModelChange)="change()"> ` }) export class ChildComponent { @Output() onChange = new EventEmitter(); sharedVar: string; change() { this.onChange.emit({value: this.sharedVar}); } }
and the in parent component:
@Component({ selector: 'parent', template: ` <h1>{{sharedVar}}</h1> <child (onChange)="sharedVar = $event.value"></child> `, directives: [ChildComponent] }) export class ParentComponent { sharedVar: string; constructor() { } }
Demo: http://plnkr.co/edit/T2KH4nGKPSy6GEvbF1Nb?p=info
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With