Angular 2属性绑定:EventEmitters如何工作?

时间:2016-10-14 23:50:31

标签: javascript angular data-binding properties

我一直在研究Angular 2双向绑定,并且我已经整理了一个演示,它将组件的属性绑定到另一个,包含组件的属性,以及几个文本字段。不幸的是,对我来说很多看起来像是magic,这使得当魔法不起作用时调试非常困难。特别是,该演示揭示了我尚未完全理解绑定的几个地方;这个问题是关于这一主题的第一个问题。

(演示位于http://plnkr.co/edit/IUTy5p?p=preview,以防您想在家中跟进......)

该代码实现了一个父组件,其中包含pName字符串属性,以及一个包含cName属性的子组件。父项的属性使用香蕉盒语法双向绑定到子项的属性:

<child [(cName)]="pName"></child>

子项内部显示cName属性,以及三个文本输入,每个输入都以某种方式绑定到cName属性。第二个文本输入是重要的一个:

<input type="text" [ngModel]="cName" (ngModelChange)="cNameChange.emit($event)">

ngModelChange事件在emit()上调用EventEmitter方法,其名称cNameChange来自cName媒体资源的名称:

@Output() public cNameChange:EventEmitter<String> = new EventEmitter<String>();

因此,如果您编辑第二个文本输入的值,则子项的cName属性会更改,其他两个文本输入会更改其值,并且父项的pName属性会更改。

但是,如何

这可以分为两个相关的问题:

  1. 如何排放该事件会改变cName属性?
  2. 如何更改子级cName属性最终更改父级pName属性?

1 个答案:

答案 0 :(得分:1)

唯一真正的魔力是[()]语法,由Angular指定。其余部分可在以下部分中解释

当我们使用[(cData)]="pData"时,它与使用

相同
[cData]="pData" (cDataChange)="pData = $event"

当事件发送到cDataChange时,Angular保证将绑定输入属性([cData]="pData")的值(在本例中为pData)设置为cDataChange发出的值{1}}

  
      
  1. 如何排放该事件会改变cName属性?
  2.   
@Component({
  template: `
    <input type="text" [ngModel]="cName" (ngModelChange)="cNameChange.emit($event)">
  `
})
export class ChildComponent {
  @Input() public cName:string = 'thisIsIgnored';
  @Output() public cNameChange:EventEmitter<String> = new EventEmitter<String>();
}

@Component({
  selector: 'parent',
  template: `
    <child [(cName)]="pName"></child>
  `
})
export class App {
  pName:string;

  constructor() {
    this.pName = 'InitialName'
  }
}

使用简化语法pData,父cData与儿童[(cData)]="pData"双向绑定。这意味着父级同时向{em> 提供了@Input('cData')并且提供了cNameChange事件,其中自动更改了绑定属性,这种情况pData。这是唯一真正神奇的部分。但它是Angular docs中描述的内容,所以我们只接受它为真。

因此,当您输入第二个子输入时,它会根据Angular规范发出cDataChange事件并更改pDatapData也是cData的输入,因此cData也需要更改以匹配pData输入。

您可以通过注释掉孩子的第一个和第三个输入,然后添加

来确认父母负责cData更改
<li>cName: {{ cName }}</li>
  
      
  1. 如何更改子级cName属性最终更改父级pName属性?
  2.   

在任何时候你都没有真正改变它(明确地)。这都是双向绑定处理的。如果您添加了 明确更改的内容,请说

<button (click)="cName = 'hello'">Change</button>

或只是输入第三个输入。当您单击按钮或键入时,您将看到更改父级,但子级会看到更改,因为他们正在从cData获取输入。只有在使用新值发出cData事件时,父级才会看到更改的唯一方法是cDataChange

那么实际上改变父亲的是前一点讨论的活动。