“可观察到的 < 事件 >”类型上不存在属性“ filter”

嗨,我使用角度2最终与路由器3.0。我想过滤从 this.router.events发出的事件

我想做的:

import 'rxjs/operator/filter';


//...


this.router.events
.filter((event:Event) => event instanceof NavigationEnd)
.subscribe(x => console.log(x))

event可以是 NavigationEndNavigationStart或者 RoutesRecognized的 instanceOf,但是我只想要 NavigationEnd。但是我得到一个错误

Property 'filter' does not exist on type Observable<Event>

在编译期间。

当我导入整个 rxjs库时,错误就消失了。我应该导入什么来使它在不加载完整的 rxjs 库的情况下工作?

89813 次浏览

更新

RXJS 5.x版本:

import 'rxjs/add/operator/filter';

对于 RXJS 6.x 版本:

import { filter } from 'rxjs/operators';

遵守规则是由 RxJS 团队设计用来提供帮助的 JavaScript 开发人员重构导入路径:

  1. 包含所有可管道操作员。

import { map, filter, scan } from 'rxjs/operators';

  1. rxjs: 包含创建方法、类型、调度程序和实用程序。

导入{可观察的,主题的,asapScheduler 的, 间隔,merge,from Event } from‘ rxjs’;

请检查此处的事件类型-> . filter ((Event: Event)

这个场景有几个可能的修复方案。

1)使用管道操作员

与在 rxjs/add/Operator/* 中找到的“补丁”操作符相比,可管道操作符是一种更好的方法,可以只引入您需要的操作符

import { filter } from 'rxjs/operators';


// ..


this.router.events.pipe(
filter((event:Event) => event instanceof NavigationEnd)
).subscribe(x => console.log(x))

2)使用‘ rxjs/add/Operator/filter’

将 import 语句更改为 import 'rxjs/add/operator/filter'。这将修改 Observable.prototype,并将 filter方法添加到每个可观察类的实例中。

结果有两个:

  • 对于每个应用程序只执行一次 import 语句就足够了
  • 在共享库/npm 包中,这可能会给库使用者带来一些混淆(在使用库时,filter()方法将神奇地出现在 Observable下)

3)保留操作符导入,但改变它的调用方式

import 'rxjs/operator/filter'语句是完全有效的。它只导入操作符。这种方法不会与 Observable.prototype混淆。不利的一面是,这将使连锁多家运营商变得更加困难。

import 'rxjs/operator/filter'; // This is valid import statement.
// It will import the operator without
// modifying Observable prototype
// ..


// Change how the operator is called
filter.call(
this.router.events,
(event:Event) => event instanceof NavigationEnd
).subscribe(x => console.log(x));

更多细节: 管道运营商

Angular Update (5.x 到6.x)还附带了 rxjs 从5.x 到6. x 的更新 简单地加上

import { filter } from 'rxjs/operators';

那么

this.router.events.pipe(
filter((event:Event) => event instanceof NavigationEnd)
).subscribe(x => console.log(x))

希望能帮到某人

在升级到 Rxjs6后,使用角度6升级。

import { map, filter, scan } from 'rxjs/operators';


...
this.registrationForm.valueChanges
.pipe(
filter(() => this.registrationForm.valid),
map((registrationForm: any) => {
this.registrationVm.username = registrationForm.username;
this.registrationVm.password = registrationForm.password;
this.registrationVm.passwordConfirm = registrationForm.passwordConfirm;
})
)
.subscribe();

解决这个问题最简单的方法就是

npm install rxjs-compat

这将使任何版本的差异神奇地消失!

请注意:

我想提及一些上述答案没有涉及的问题。

RxJs 是一个独立的库,因此它的操作也是独立的方法。Map、 filter 等是不通过对象访问的操作符方法。请记住,您需要分别导入它们。

因此,例如,您不能 import { filter},并希望通过 router对象访问它。这是行不通的,因为 router对象是 API 中某个特定于角度的类实例。Angular 提供了一个 pipe()方法,它允许您注册必须在进程中链接的方法,然后在 router中移动到不属于 router对象的下一个方法。

永远记住这一点

transform(value: any,  args?: any): unknown {
if(!args)
return value;
return value.filter(item => item.title)
}


transform(value: any,  args?: any): unknown {
if(!args)
return value;
return value.filter(item => item.title)
}

如果这样显示滤波器错误使用,主要是 value:any工作正常。