事件发射器绑定

Event Emitter Binding

我正在阅读由 O'Reilly 出版的 Shyam Seshadri 的 "Angular Up and Running"。在关于输出和事件发出的讨论中,我有点困惑。

一个组件中的EventEmitter声明、初始化和实现为:

@Output() private toggleFavorite: EventEmitter<Stock>;

constructor() {
 this.toggleFavorite = new EventEmitter<Stock>();
}

onToggleFavorite(event) {
 console.log('We are toggling the favorite state for this stock.', event);
 this.toggleFavorite.emit(this.stock);
}

app.component.html 中的绑定为:

(toggleFavorite)="appToggleFavorite($event)"

但是app.component.ts中的方法定义为:

appToggleFavorite(stock: Stock) {
 console.log('Favorite for stock ', stock, ' was triggered.');
}

如果绑定正在传递 $event 对象,并且绑定方法需要 Stock 类型,为什么会这样?

(它确实有效,我已经测试过了。)

我不是在问 $event 对象的作用,我已经知道了。请仔细阅读我上面的问题。我在问:当绑定函数需要类型化参数时,为什么绑定到 EventEmitter 对象传递的是 $event 对象而不是预期类型的​​对象,为什么它似乎有效(参数将其值作为输入。)

我最好的猜测是,仔细看看下面的 appToggleFavorite 函数。

appToggleFavorite(stock: Stock) {
 console.log('Favorite for stock ', stock, ' was triggered.');
}

如果它在编译时被调用,它会抛出一个错误说appToggleFavorite期待一个Stock类型的arg但是没有给。

但是 appToggleFavorite 运行时被调用 ,而在运行时,它只是 HTML 和 JavaScript。它不关心作为 argappToggleFavorite 收到的内容。因此它起作用了。

简单说一下,子组件可以通过 Output 属性 让父组件知道一些事情。这个 Output 属性 然后将被父组件的模板用作 event。所以要监听 Output 属性,需要一个事件绑定。只要在 EventEmitter 上调用 emit 方法(作为 Output 属性 公开),就会调用分配给此事件绑定的处理函数。仅当使用保留关键字 $event 时,Handler 函数才能获取传递给 emit 函数 的数据。

从技术上讲,$event 是不必要的并且会造成混淆。

(toggleFavorite)="appToggleFavorite()"

也将起作用,因为您暗示当您调用 .emit 时,您将调用 appToggleFavorite 并使用赋予 .emit 的任何值类型。 Javascript 是一种无类型语言,所以它会在 运行 时间工作。

它是 TypeScript 高级类型 ,而不是 Angular。当您声明时:

@Output() private toggleFavorite: EventEmitter<Stock>;

toggleFavorite 的类型是 <Stock> 并且编译器是“waiting”这个类型在 return 的值。
这个doc是对的here.