类型x的参数不能分配给类型'(x)=> ObservableInput <{}>的参数

时间:2018-06-28 13:59:26

标签: angular typescript rxjs ngrx

希望有人可以对此有所启发

使用ngrx并尝试使用多个switchMap来调用某些操作类。

我的动作:

export class BlogAddedAction implements Action {

    readonly type = BLOG_ADDED_ACTION;

    constructor(public payload:any) {

    }

}
export class CrudSucessAction implements Action {

    readonly type = CRUD_SUCCESS_ACTION;

    constructor(public payload:any) {

    }
}

export class BlogAddedToDBAction implements Action {

    readonly type = BLOG_ADDED_TO_DB_ACTION;

    constructor(public payload:any) {

    }
}

effects.ts:

  @Effect() addBlog$: Observable<any> = this.actions$
  .ofType<BlogAddedAction>(BLOG_ADDED_ACTION)
    .switchMap(action =>  {
        console.log(action)
    return this.blogService.addBlog(action.payload.blog)
    })
    .switchMap((action)=>new BlogAddedToDBAction(action))
    .map((action)=>new CrudSucessAction(action))
}

但是我收到Typescript错误:

[ts]
Argument of type '(action: Blog) => BlogAddedToDBAction' is not 
assignable to parameter of type '(value: Blog, index: number) => ObservableInput<{}>'.Type 'BlogAddedToDBAction' is not assignable to type 'ObservableInput<{}>'.
Type 'BlogAddedToDBAction' is not assignable to type 'ArrayLike<{}>'.Property 'length' is missing in type 'BlogAddedToDBAction'.

尝试使用map而不是第二个switchMap,但是BlogAddedToDBAction未执行。

1 个答案:

答案 0 :(得分:1)

当您要发出可以取消的Observable时,应使用

switchMap-在这种情况下,这是addBlog http请求。在这种情况下,您很可能希望使用mergeMap,因为如果您尝试在添加前一个博客之前添加一个博客,它将被取消。参见:https://blog.angularindepth.com/switchmap-bugs-b6de69155524

switchMap要求发出一个Observable-compatible值,因此您不能返回像BlogAddedToDBAction这样的普通对象。相反,您可以执行of(new BlogAddedToDBAction(action)),因为of将创建一个Observable发出该对象-但是这可能不是您想要的。

Effect是发出动作的单个Observable流。您的流仅发出CrudSuccessAction

似乎您可能想同时发出两个动作。为此,您可以使用merge。然后,“可观察的效果”将依次发出每个动作。我会这样写:

@Effect() addBlog$: Observable<any> = this.actions$.pipe(
  ofType<BlogAddedAction>(BLOG_ADDED_ACTION),
  mergeMap(action =>  {
    console.log(action)
    return this.blogService.addBlog(action.payload.blog).pipe(
      mergeMap(action => [new BlogAddedToDBAction(action), new CrudSucessAction(action)]),
      catchError(() => of(new CrudErrorAction())
  });
带有数组的

mergeMap将发出该数组的每个值。您可以使用简单的测试来确认这一点:

of(1).pipe(mergeMap(() => [1, 2])).subscribe(console.log); // logs 1, then 2