组件输入属性

时间:2016-01-05 09:59:53

标签: data-binding angular bidirectional

我正在尝试使用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>

testStringMyApp.ts中定义的包含字符串的变量。我希望在用户修改testString时修改我的inputText变量。

这是一个带有简单示例代码的Plunker:https://plnkr.co/edit/zQiCQ3hxSSjCmhWJMJph?p=preview

有没有办法简化这项工作?我是否必须在我的自定义组件和重载函数上实现Angular2类,以使其像ngModel一样工作?我是否必须创建一个inputTextChanged类型的EventEmitter变量,在变更时发出我的数据并执行以下操作:

<my-comp [inputText]="testString" (inputTextChanged)="testString = $event;"></my-comp>

提前谢谢。

4 个答案:

答案 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>