Angular 2 - 在组件之间交换数据(没有服务)

Angular 2 - Exchanging data among components (without services)

使用服务共享全球数据看起来不错。但我相信这种做法并不是仅与其他组件共享数据的最佳方式。可以将全局变量存储在服务中,例如登录用户、设置或任何其许多组件需要检索数据的东西。

当一个组件需要向另一个组件发送数据时,我更喜欢某种直接通信。关于此的文档非常少,在许多情况下,适用于 Angular 2 Beta 的过时版本。

我正在尝试创建一些非常原始的东西以放置在 public 存储库中,供有相同需求但在发射器方面遇到困难的人使用。

当我使用 EventEmitter 时,我找不到使一个组件 "listen" 成为另一个组件的事件的方法。

下面的通用示例基本上是关于 child 组件向 parent 发送数据。当用户键入 "fire".

时,最终结果必须是显示 "boom" 的反馈变量

app.component.ts

import {Component} from 'angular2/core';
import {ParentComponent} from './parent.component'
@Component({
selector: 'my-app',
directives : [ParentComponent],
template: `<h1>My App</h1>
<parent-component></parent-component>
`
})
export class AppComponent { 

}

parent.component.ts

import {Component} from 'angular2/core';
import {ChildComponent} from './child.component'
@Component({
selector: 'parent-component',
directives : [ChildComponent]
template: `<p>I'm the parent component</p>
<input type="textbox" [(ngModel)]="theModel">
<p>feedback: {{feedback}}</p><!--THIS IS WHERE THE BOOM MUST APPEAR-->
<child-component txt="{{theModel}}"></child-component>
`
})
export class ParentComponent { 
   theModel;
}

child.component.ts

import {Component, Input, OnChanges, EventEmitter,Output, Injectable}    from 'angular2/core';
@Injectable()
@Component({
selector: 'child-component',
template: `<p>I'm the child component</p>
`
})
export class ChildComponent implements OnChanges { 
@Input() txt: string;
@Output() aim: EventEmitter<any> = new EventEmitter();
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    var t = changes['txt'].currentValue;
    if(t == 'fire') {
        console.log('Fire !!!');
        this.kill.aim("booom !!!");
    }
}
}

我需要找到一种方法来捕获 child 组件发出的事件。 我看到了几个类似需求的例子,但看起来 angular 2 你有很多方法可以做同样的事情,所以通常这些例子只适用于一个场景——这就是为什么我要创建一些没有 [=43 的通用的东西=] 特别适合任何需要。顺便说一句,我不确定 child 发出一些东西是否真的是最好的方法。随时与更好的方法进行协作。

您使用 (aim)="feedback=$event"

向子组件的事件注册了一个动作
import {Component} from 'angular2/core';
import {ChildComponent} from './child.component'

@Component({
  selector: 'parent-component',
  directives : [ChildComponent]
  template: `
<p>I'm the parent component</p>
<input type="textbox" [(ngModel)]="theModel">
<p>feedback: {{feedback}}</p><!--THIS IS WHERE THE BOOM MUST APPEAR-->
<child-component txt="{{theModel}}" (aim)="feedback=$event"></child-component>`
})
export class ParentComponent { 
   feedback;
   theModel;
}

您使用 this.aim.emit(someValue)

发出一个事件供家长收听
import {Component, Input, OnChanges, EventEmitter,Output, Injectable}    from 'angular2/core';

@Injectable()
@Component({
  selector: 'child-component',
  template: `<p>I'm the child component</p>`
})
export class ChildComponent implements OnChanges { 
  @Input() txt: string;
  @Output() aim: EventEmitter<any> = new EventEmitter();
  ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    var t = changes['txt'].currentValue;
    if(t == 'fire') {
        console.log('Fire !!!');
        // this.kill.aim("booom !!!");
        this.aim.emit("boom");
    }
  }
}

更多详情https://angular.io/docs/ts/latest/guide/template-syntax.html#!#event-binding

Simple example - EventEmitter

parent.ts

<input type="textbox" [(ngModel)]="theModel">
<child-component txt="{{theModel}}" (aim)=onEdit($event)></child-component>

onEdit(arg){  // this function is optional you my also try what Gunter has suggested.
   console.log(arg);
   this.feedback=arg;
}

child.ts

@Input() txt: string;
@Output() aim: EventEmitter<any> = new EventEmitter();

ngOnChanges(changes: {[propName: string]: SimpleChange}) {
var t = changes['txt'].currentValue;
 if(t == 'fire') {
    console.log('Fire !!!');
       this.aim.emit("boom");
 }
}
...

注意你可以传递对象,正如上面link.