Hice una interfaz de usuario simple que consta de dos componentes (padre e hijo).
Lo que hace la interfaz de usuario es que cuando escribo algunas cosas en el cuadro de entrada del componente secundario. El valor cambiará usando ngModel.
El componente hijo funciona bien de esa manera.
// Child Component @Component({ selector: 'child', template: ` <p>{{sharedVar}}</p> <input [(ngModel)]="sharedVar"> ` }) export class ChildComponent { sharedVar: string; }Ahora tengo un componente principal que tengo la intención de usar el mismo valor que el componente secundario.
Agregué el componente secundario en la plantilla principal y utilicé la inyección de dependencia para llamar a sharedVar del componente secundario.
// 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; } } El problema es que mientras escribo en el cuadro de entrada, el valor en <p> cambia automáticamente mientras que el valor en el componente principal <h1> no cambia.
Podemos usar la sintaxis [(x)] en la plantilla principal para lograr un enlace de datos bidireccional con el elemento secundario. Si creamos una propiedad de salida con el nombre xChange , Angular actualizará automáticamente la propiedad principal. Sin embargo, necesitamos emit() un evento cada vez que el niño cambia el valor:
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(); } } sharedVarParent en ParentComponent solo para demostrar que los nombres no tienen que ser los mismos en el padre y el hijo.
Puede configurar la comunicación del emisor de eventos ( outputs ) de niño a padre. Por ejemplo como este:
@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}); } }y el componente principal:
@Component({ selector: 'parent', template: ` <h1>{{sharedVar}}</h1> <child (onChange)="sharedVar = $event.value"></child> `, directives: [ChildComponent] }) export class ParentComponent { sharedVar: string; constructor() { } }Demostración: http://plnkr.co/edit/T2KH4nGKPSy6GEvbF1Nb?p=info
Y si desea tener múltiples enlaces de datos bidireccionales en el mismo componente, puede hacerlo
export class ComponentName { @Input() public first: string = ''; @Input() public second: string = ''; @Output() public firstChange = new EventEmitter(); @Output() public secondChange = new EventEmitter(); public functionName1(first: string): void { this.first = first; this.firstChange.emit(first); } public functionName2(second: string): void { this.second = second; this.secondChange.emit(second); } }Cuando la entrada y la salida se denominan 'x' y 'xChange', las detecta automáticamente en el padre que pertenecen juntas.
Creo que esta es en realidad una mejor práctica que la de la respuesta aceptada, porque aquí deja en claro de inmediato cómo se relacionan los nombres.