我正在尝试使用angular2进行操作,但我无法找到有关此行为的内容。
我有一个应用程序实现了这样的自定义组件:
import {Component,Input} from 'angular2/core'
@Component({
selector:'my-comp',
template:`<input type="text" style="text-align:center; [(ngModel)]="inputText"> <p>{{inputText}}</p>`
})
export class MyComp{
@Input() inputText : string;
}
我正在尝试对我的组件inputText
变量进行双向数据绑定,如下所示:
<my-comp [(inputText)]="testString"></my-comp>
testString
是MyApp.ts
中定义的包含字符串的变量。我希望在用户修改testString
时修改我的inputText
变量。
这是一个带有简单示例代码的Plunker:https://plnkr.co/edit/zQiCQ3hxSSjCmhWJMJph?p=preview
有没有办法简化这项工作?我是否必须在我的自定义组件和重载函数上实现Angular2类,以使其像ngModel
一样工作?我是否必须创建一个inputTextChanged
类型的EventEmitter
变量,在变更时发出我的数据并执行以下操作:
<my-comp [inputText]="testString" (inputTextChanged)="testString = $event;"></my-comp>
提前谢谢。
答案 0 :(得分:22)
这在Two-Way Binding with NgModel部分的模板语法文档中进行了解释:
<input [(ngModel)]="currentHero.firstName">
在内部,Angular将术语
ngModel
映射到ngModel
输入属性和ngModelChange
输出属性。这是一个更一般的模式的一个具体示例,它将[(x)]
与Property Binding的x
输入属性匹配,并将事件绑定的xChange
输出属性匹配。如果我们有心情这样做,我们可以编写自己的双向绑定指令/组件。
另请注意,[(x)]
只是属性绑定和事件绑定的语法糖:
[x]="someParentProperty" (xChange)="someParentProperty=$event"
在你的情况下,你想要
<my-comp [(inputText)]="testString"></my-comp>
因此,您的组件必须具有inputText
输入属性和inputTextChange
输出属性(EventEmitter
)。
export class MyComp {
@Input() inputText: string;
@Output() inputTextChange: EventEmitter<string> = new EventEmitter();
}
要通知父级更改,只要组件更改inputText
的值,就会发出一个事件:
inputTextChange.emit(newValue);
在您的场景中,MyComp组件使用inputText
格式将输入属性[(x)]
绑定到ngModel,因此您使用事件绑定(ngModelChange)
来通知更改,并在该事件处理程序中您已通知更改的父组件。
在未使用ngModel的其他情况下,重要的是{My}组件中属性emit()
的值发生变化时inputText
事件。
答案 1 :(得分:7)
我会将@pixelbits和@GünterZöchbauer的答案和评论结合起来,以便在我的问题上做出明确答案,如果将来某人正在搜索这个问题。
要使双向数据绑定适用于自定义变量,您需要根据以下内容创建组件。
MyComp.ts文件:
import {Component,Input,Output,EventEmitter} from 'angular2/core'
@Component({
selector:'my-comp',
templateUrl:`<input type="text" style="text-align:center;"
[ngModel]="inputText" (ngModelChange)="inputText=$event;inputTextChange.emit($event);">`
})
export class MyComp{
@Input() inputText : string;
@Output() inputTextChange = new EventEmitter();
}
MyApp.ts文件:
import {Component} from 'angular2/core'
import {MyComp} from './MyComp'
@Component({
selector:'my-app',
templateUrl:`<h1>Bidirectionnal Binding test </h1>
<my-comp [(inputText)]="testString"></my-comp><p>
<b>My Test String :</b> {{testString}}</p>`,
directives:[MyComp]
})
export class MyApp{
testString : string;
constructor(){
this.testString = "This is a test string";
}
}
与inputText
变量的双向数据绑定正常工作。
您可以对答案进行评论,以获得更美观或更简单的方法来实现此代码。
答案 2 :(得分:1)
您的Plunker已包含EventEmitter
。缺少@Output()
注释。要更改值调用inputTextChanged.emit(newValue)
(这也会更改inputText
上的值)
答案 3 :(得分:-1)
我所做的是使用属性,因此当我更改数据时,更改会自动发出
private _data: AnyType;
@Input() get data(): AnyType{
return this._data;
}
set data(value: AnyType) {
this._data = value;
this.dataChange.emit(this._data);
}
@Output() dataChange: EventEmitter<AnyType> = new EventEmitter();
在html中,您将使用[(data)]
绑定属性<comp [(data)]="getData()"></comp>