Versión: "angular2": "2.0.0-beta.6"
Me gustaría implementar un enlace bidireccional dentro de un caso de componente principal/secundario.
En mi componente secundario, estoy usando un enlace bidireccional para mostrar el texto durante la edición.
Componente secundario ( InputTestComponent [selector:'input-test'] ):
<form (ngSubmit)="onSubmit()" #testform="ngForm"> {{name}} <textarea #textarea [(ngModel)]="name" ngControl="name" name="name"></textarea> <button type="submit">Go</button> </form> Luego, me gustaría propagar este cambio a su componente principal. Intenté con [(name)]="name" sin éxito.
Componente principal:
<div> {{name}} <input-test [(name)]="name"></input-test> </div>¿Cuál es la forma más fácil de hacerlo (menos detallada)?
Para el enlace bidireccional, use @Input() y @Output() . Los nombres deben ser propName y propNameChange para permitir la sintaxis de enlace abreviado [(propName)]="someModel" lo contrario, necesitaría la versión más larga [propName]="someModel" (propNameOtherOutputName)="propName=$event;propNameOtherOutputName.emit($event)"
@Component{ ... template: ` <textarea #textarea [(ngModel)]="name" (ngModelChange)="nameChange.emit($event)" ngControl="name" name="name"></textarea> `}) export class InputTestComponent { @Output() nameChange:EventEmitter<String> = new EventEmitter<String>(); @Input() name:string; }Puede configurar el enlace de datos bidireccional entre el componente principal y el secundario de las siguientes maneras:
<app-child [(counter)]="counter"></app-child> <app-child [counter]="counter" (counterChange)="counter=$event"></app-child> <app-child [counter]="counter" (counterChange)="onCounterChange($event)"></app-child>De acuerdo con Angular - Sintaxis de plantilla - Enlace bidireccional :
Angular ofrece una sintaxis de enlace de datos bidireccional especial para este propósito, [(x)]. La sintaxis [(x)] combina los corchetes del enlace de propiedades, [x], con los paréntesis del enlace de eventos, (x).
<app-child [(counter)]="counter"></app-child>La sintaxis [(x)] es fácil de demostrar cuando el elemento tiene una propiedad configurable llamada x y un evento correspondiente llamado xChange.
@Input() counter: number; @Output() counterChange = new EventEmitter<number>();La sintaxis de enlace bidireccional es realmente azúcar sintáctica para un enlace de propiedad y un enlace de evento. Angular elimina el enlace ChildComponent en esto:
<app-child [counter]="counter" (counterChange)="counter=$event"></app-child>Ejemplo: https://stackblitz.com/edit/angular-two-way-data-binding- between -parent-and-child-component?file=src%2Fapp%2Fapp.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div style="background-color: red; padding: 10px;"> <div>{{counter}}</div> <button (click)="increment()">increment from parent</button> <app-child [(counter)]="counter"></app-child> <app-child [counter]="counter" (counterChange)="counter=$event"></app-child> <app-child [counter]="counter" (counterChange)="onCounterChange($event)"></app-child> </div> ` }) export class AppComponent { counter = 0; increment() { this.counter++; } onCounterChange(counter: number) { this.counter = counter; } } @Component({ selector: 'app-child', template: ` <div style="background-color: green; padding: 10px; margin: 10px;"> <div>{{counter}}</div> <button (click)="increment()">increment from child</button> </div> `, }) export class ChildComponent { @Input() counter: number; @Output() counterChange = new EventEmitter<number>(); constructor() { } increment() { this.counterChange.emit(++this.counter); } }Debe usar elementos de entrada/salida en el componente secundario, como se describe a continuación:
@Component({ selector:'input-test' template: ` <form (ngSubmit)="onSubmit()" #testform="ngForm"> {{name}} <textarea #textarea [(ngModel)]="name" ngControl="name" name="name"></textarea> <button type="submit">Go</button> </form> ` }) export class InputTestComponent { @Input() name:string; @Output() nameChange:EventEmitter<string> = new EventEmitter(); } Cuando se detecta un cambio, debe activar un evento utilizando EventEmitter :
onSubmit() { this.nameChange.emit(this.name); }De esta forma, el elemento vinculado del componente principal se actualizará automáticamente cuando se utilice la siguiente sintaxis:
<input-test [(name)]="name"></input-test> Puede notar que puede aprovechar el evento ngModelChange si desea detectar cambios de entrada en lugar de utilizar el envío de formularios:
@Component({ selector:'input-test' template: ` <form #testform="ngForm"> {{name}} <textarea #textarea [ngModel]="name" (ngModelChange)="onChange($event)" ngControl="name" name="name"></textarea> </form> ` }) export class InputTestComponent { @Input() name:string; @Output() nameChange:EventEmitter<string> = new EventEmitter(); onChange(newName) { this.name = newName; this.nameChange.emit(this.name); } }