组件输入属性上的双向数据绑定

Posted

技术标签:

【中文标题】组件输入属性上的双向数据绑定【英文标题】:Bidirectional data binding on a component input property 【发布时间】:2016-04-09 02:35:59 【问题描述】:

我正在尝试对 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 中定义的变量,其中包含一个字符串。当我的inputText 被用户修改时,我希望我的testString 变量被修改。

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

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

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

提前谢谢你。

【问题讨论】:

是的,您必须创建一个事件发射器“inputTextChanged”,并在组件内部触发该事件。然后 [(inputText)] 应该按预期工作。 请注意:Angular2 中没有双向数据绑定之类的东西,但您可以有类似的行为。 victorsavkin.com/post/110170125256/… 根据官方网站的Angular2 Cheat Sheet:" 设置双向数据绑定。相当于:"。所以我认为我们可以说Angular2中有双向数据绑定。 @jornare,我认为你/Savkin 和 David 都是正确的。我相信 Savkin 试图表明 Angualr 2 中没有代码来处理双向数据绑定。即,[(something)] 只是一个属性绑定和一个事件绑定的语法糖。所以 Angular 不会将 [(something)] 视为一个双向数据绑定,而是将其视为两个单向数据绑定。 【参考方案1】:

这在模板语法文档的Two-Way Binding with NgModel 部分中进行了解释:

&lt;input [(ngModel)]="currentHero.firstName"&gt;

在内部,Angular 将术语 ngModel 映射到 ngModel 输入属性和 ngModelChange 输出属性。这是一个更通用模式的具体示例,其中将[(x)] 匹配到属性绑定的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 组件使用 [(x)] 格式将输入属性 inputText 绑定到 ngModel,因此您使用事件绑定 (ngModelChange) 来获得更改通知,并在该事件处理程序中通知父组件变化。

在不使用 ngModel 的其他场景中,重要的是每当 MyComp 组件中属性 inputText 的值发生变化时,emit() 一个事件。

【讨论】:

更新 Angular4:在子组件中不再需要指定 EventEmitter 输出。这是由@input 自动处理的。父视图: 子组件:export class MyComp @Input() inputText: string; 【参考方案2】:

如果将来有人搜索此问题,我将结合 @pixelbits 和 @Günter Zöchbauer 的答案和 cmets 来明确回答我的问题。

要使双向数据绑定适用于自定义变量,您需要根据以下内容创建组件。

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 变量的双向数据绑定工作正常。 您可以评论答案以获得更漂亮或更简单的方式来实现此代码。

【讨论】:

【参考方案3】:

您的 Plunker 已包含 EventEmitter。缺少 @Output() 注释。要更改值调用inputTextChanged.emit(newValue)(这也会更改inputText 上的值)

【讨论】:

是的,抱歉,我是 plunker 新手,忘记将 plunker 锁定到我希望您看到的状态,并继续对其进行测试,以便您看到我的修改。 我记得,我不知道你是否知道,但至少从 Angular2 的 beta 版本开始,“.next()”已被弃用,你应该使用“.emit()”。 谢谢!没见过。【参考方案4】:

我所做的是使用一个属性,所以当我更改数据时,更改会自动发出

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>

【讨论】:

以上是关于组件输入属性上的双向数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

Angular 手动实现ngModal数据双向绑定

vue3自定义组件使用v-model实现双向数据绑定

带有@input属性的Angular 7双向绑定

Angular09 数据绑定响应式编程管道

Angular2:使用DynamicComponentLoader动态插入的组件上的双向数据绑定

Angular自定义组件实现数据双向数据绑定