版本:" angular2":" 2.0.0-beta.6"
我想在父/子组件案例中实现双向绑定。
在我的子组件上,我使用双向绑定在编辑时显示文本。
子组件(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>
然后,我想将此更改传播到其父组件。
我尝试使用[(name)]="name"
但没有成功。
父组件:
<div>
{{name}}
<input-test [(name)]="name"></input-test>
</div>
最简单的方法(更简洁)?
答案 0 :(得分:35)
对于双向绑定,请使用@Input()
和@Output()
。名称应为propName
和propNameChange
以允许速记绑定语法[(propName)]="someModel"
,否则您需要更长的版本[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;
}
答案 1 :(得分:2)
您需要在子组件中使用输入/输出元素,如下所述:
@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();
}
检测到更改时,您需要使用EventEmitter
onSubmit() {
this.nameChange.emit(this.name);
}
这样,使用以下语法时,父组件的绑定元素将自动更新:
<input-test [(name)]="name"></input-test>
如果您想检测输入更改而不是使用表单提交,您可以注意到可以利用ngModelChange
事件:
@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);
}
}
答案 2 :(得分:2)
您可以通过以下方式设置父组件和子组件之间的双向数据绑定:
<app-child [(counter)]="counter"></app-child>
<app-child [counter]="counter" (counterChange)="counter=$event"></app-child>
<app-child [counter]="counter" (counterChange)="onCounterChange($event)"></app-child>
根据Angular - Template Syntax - Two-way binding:
Angular为此提供了一种特殊的双向数据绑定语法, [(X)]。 [(x)]语法结合了属性绑定的括号, [x],带有事件绑定的括号,(x)。
<app-child [(counter)]="counter"></app-child>
当元素具有a时,[(x)]语法很容易演示 名为x的可设置属性和名为xChange的相应事件。
@Input() counter: number;
@Output() counterChange = new EventEmitter<number>();
双向绑定语法实际上只是一个语法糖 属性绑定和事件绑定。 Angular desugars the ChildComponent绑定到此:
<app-child [counter]="counter" (counterChange)="counter=$event"></app-child>
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);
}
}
答案 3 :(得分:1)
是的,我们可以使用banana属性来共享子节点到父节点之间的数据
[(propertyname)]
和propertynameChange
发射器事件。
样本plunker可用https://plnkr.co/edit/FYXv36?p=preview
答案 4 :(得分:0)
您可以使用@Input和@Output实现父级和子级之间的2种方式绑定,如先前的答案所述。
否则,还有另一种解决方案,您可以使用包含变量的服务,并且可以通过ngModel从不同组件(即使它们不是父子组件)同时访问它