【问题标题】: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)] 视为一个双向数据绑定,而是将其视为两个单向数据绑定。

标签: data-binding angular bidirectional


【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 2019-10-01
      • 2019-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多