Angular v17.3 引入了改进的 API,用于将 outputs 声明为开发人员预览版。
新的 outputs API 为开发人员提供:
EventEmitter
的 @Output
API 不能保证适当的类型安全,并且可能会导致微妙的运行时错误出现。新的 output API 现已在开发者预览版中提供,我们希望收到您的反馈。
Outputs 允许组件作者向父组件发出值。我们引入了一个新的 API 来声明 outputs,该 output 与我们在 v17 中宣布的其他基于函数的 API(例如 signal inputs)紧密结合。
有两个新函数可用于声明 outputs:
.emit
函数来发出值。需要注意的是,这个新 API 不是一个 signal,而是一个更符合人体工程学的 API,可以减少样板代码。
要开始使用这个新 API,请从 @angular/core
导入 output 函数:
import { output } from `@angular/core`;
接下来,在组件中声明一个类字段并通过调用 output()
函数对其进行初始化。字段名称将用作 output 的公共名称:
import { Component, output } from '@angular/core';
@Component({…})
export class MyComp {
onNameChange = output<string>(); // OutputEmitterRef<string>
}
然后,您可以通过调用 OutputEmitterRef
上的 emit
函数向 output 发出新值:
class MyComp {
// …
updateName(newName: string) {
this.onNameChange.emit(newName);
}
}
父组件可以使用事件绑定语法绑定到模板中的 onNameChange
output,类似于使用基于装饰器的 @Output
声明的 outputs。
<!-- parent component template -->
<app-my-comp (onNameChange)="handleNameChange($event)" />
除了新的 output()
函数之外,Angular 还提供了无缝集成 RxJS 的 outputFromObservable()
函数。
如果您的应用程序需要方便地公开 RxJS 流中的值,您可以使用此函数来声明使用 observable 作为源的 Angular output。
这样,您仍然可以利用 observables 的功能,同时受益于改进的 output API。
首先,从 @angular/core/rxjs-interop
RxJS 互操作包导入该函数,并调用该函数作为类成员的初始化程序。字段名称将用作 output 的公共名称。
import { outputFromObservable } from '@angular/core/rxjs-interop';
然后,在组件类中使用 outputFromObservable
的结果作为值初始化类字段:
@Component({…})
export class MyComp {
onNameChange$ = new Observable<string>( … );
onNameChange = outputFromObservable(this.onNameChange$);
// ^ OutputRef<string>
}
与基于装饰器的 @Output 相比,这个新的 API 提供了许多好处:
EventEmitter
类的长期存在的问题,我们改进了新 outputs 的类型安全性。现在,.emit
函数是完全类型安全的,并且不接受不应发出的值。如今,在 Angular 中,开发人员通过访问 directive 实例并在 outputs 类成员上调用 .subscribe
方法,以编程方式监听 outputs。我们希望通过围绕 outputs 提供良好的护栏和一致的解决方案来改进这方面的最佳实践。
为了开始这项工作,Angular 引入了一个一致的 API 接口,所有 outputs 都应实现该接口。所有新 outputs 和 EventEmitter
类现在都实现 OutputRef
接口。 OutputRef
是对 Angular outputs 的引用,可用于侦听新值。
export interface OutputRef<T> {
/**
* Registers a callback that is invoked whenever the output
* emits a new value of type `T`.
*
* Angular will automatically clean up the subscription when
* the directive/component of the output is destroyed.
*/
subscribe(callback: (value: T) => void): OutputRefSubscription;
}
这使得开发人员能够继续一致地监听 outputs,无论是使用新的 outputs API 还是基于装饰器的 @Output
API。
我们还在 RxJS 互操作包中添加了一个额外的帮助程序,允许以 RxJS 惯用的方式监听 outputs。这是 @angular/core/rxjs-interop
中的新 outputToObservable
函数。
import { outputToObservable } from '@angular/core/rxjs-interop';
outputToObservable(this.myComp.instance.onNameChange) // Observable<string>
.pipe(…)
.subscribe(…);
我们非常高兴能够在开发者预览版中将此功能引入 Angular 社区。新的 outputs API 现在即可使用。开发者预览版允许我们根据从社区收到的反馈进行更改。
考虑到这一点,当我们继续稳定新的 outputs API 或之前宣布的 signal inputs 功能等时,我们希望得到您的反馈。
您的反馈很有价值,我们期待您的来信。如果您有反馈意见,请考虑在GitHub或X上的评论中告知我们。
请务必通过 ng update
安装最新版本的 Angular 来尝试一下。谢谢并让我们了解最新情况。
原文链接:https://blog.angular.dev/meet-angulars-new-output-api-253a41ffa13c
翻译原文:https://zhuanlan.zhihu.com/p/689494561