Angular 6和rxjs6-管道运算符-类型'Observable <>'提供的签名不匹配

时间:2018-09-07 20:46:04

标签: angular rxjs6

我有一个在版本6之前的Angular中这样编写的搜索功能:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';

import { Product } from '../products/product';
import { ProductService } from '../products/product.service';
import { Subscription } from 'rxjs';
import { SearchService } from '../services/search-service';
import { Router } from '@angular/router';
import { PagedList } from '../shared/paged-list.interface';

@Component({
  selector: 'fb-product-list',
  templateUrl: './product-list.component.html'
})
export class ProductListComponent implements OnInit, OnDestroy {
  total$: Observable<number>;
  items$: Observable<Product[]>;

  product: Product;
  subTimer: Subscription;

  term: string = "";
  currentPage: number = 1;
  private pageStream = new Subject<number>();

  public pluralizeMapProduct: any = {
    '=0': 'No products',
    '=1': '1 product',
    'other': '# products'
  }

  constructor(
    private _searchService: SearchService,
    private _productService: ProductService,
    private _router: Router) {
  }

  ngOnInit() {
    this.setupSearching();
  }

  setupSearching(){
    const searchSource = this._searchService.searchTermStream
      .map(searchTerm => {
        this.term = searchTerm;
        return {search: searchTerm, page: 1}
      });

    const pageSource = this.pageStream.map(pageNumber => {
      this.currentPage = pageNumber;
      return {search: this.term, page: pageNumber}
    });

    const source:Observable<PagedList<any>> = pageSource
      .merge(searchSource)
      .startWith({search: this.term, page: this.currentPage})
      .switchMap((params: {search: string, page: number}) => {
        return this._productService.getProductsPaged(params.search, params.page, null, null)
      })
      .share();

    this.total$ = source.pluck('meta').pluck('total_count') as Observable<number>;
    this.items$ = source.pluck('data') as Observable<Product[]>;
  }

  goToPage(page: number, reload: boolean) {
    this.pageStream.next(page);
  }  

}

现在按照以下准则对其进行了重写:

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Subscription, Observable, Subject, merge } from 'rxjs';
    import { map, startWith, switchMap, share, pluck } from 'rxjs/operators';

    import { Product } from '../products/product';
    import { ProductService } from '../products/product.service';
    import { SearchService } from '../services/search-service';
    import { Router } from '@angular/router';
    import { PagedList } from '../shared/paged-list.interface';
    import { SearchSpec } from '../shared/search-spec.interface';

    @Component({
      selector: 'fb-product-list',
      templateUrl: './product-list.component.html'
    })
    export class ProductListComponent implements OnInit, OnDestroy {
      total$: Observable<number>;
      items$: Observable<Product[]>;

      product: Product;
      subTimer: Subscription;

      term: string = "";
      currentPage: number = 1;
      private pageStream = new Subject<number>();

      public pluralizeMapProduct: any = {
        '=0': 'No products',
        '=1': '1 product',
        'other': '# products'
      }

      constructor(
        private _searchService: SearchService,
        private _productService: ProductService,
        private _router: Router) {
      }

      ngOnInit() {
        this.setupSearching();
      }

      setupSearching(){
        const searchSource = this._searchService.searchTermStream
          .pipe(
            map(searchTerm => {
              this.term = searchTerm;
              return {term: searchTerm, page: 1} as SearchSpec
            })
          );

        const pageSource = this.pageStream
          .pipe(
            map(pageNumber => {
              this.currentPage = pageNumber;
              return {term: this.term, page: pageNumber} as SearchSpec
            })
          );

        const source:Observable<PagedList<any>> = pageSource
          .pipe(        
            merge(searchSource),
            startWith({term: this.term, page: this.currentPage}),
            switchMap((params: {term: string, page: number}) => {
              return this._productService.getProductsPaged(params.term, params.page, null, null)
            }),
            share()
          );

        this.total$ = source.pipe(pluck('meta'), pluck('total_count')) as Observable<number>;
        this.items$ = source.pipe(pluck('data')) as Observable<Product[]>;
      }

      goToPage(page: number, reload: boolean) {
        this.pageStream.next(page);
      }  

    }

VSCode在管道内的第三个const中抱怨此行:

merge(searchSource),

出现错误:

  

类型“ Observable”的参数不能分配给   类型为“ OperatorFunction”的参数。

     

类型“可观察”不提供签名的匹配项   '(来源:可观察):可观察<{}>'

我理解的

(这是参数不匹配,因为在rxjs6中我们必须使用OperatorFunctions),但是我不知道如何解决它。


编辑

这是搜索服务(适用于v6):

import { Injectable } from '@angular/core';

import { Subject } from 'rxjs';

@Injectable()
export class SearchService {

  searchTermStream = new Subject<string>();

  sendSearchTerm(term: string) {
    this.searchTermStream.next(term)
  }

}

这是我添加的用于强制键入的新接口SearchSpec:

export interface SearchSpec {
  term: string,
  page: number
}

2 个答案:

答案 0 :(得分:3)

您只需要更改导入,它实际上应该是:

import { merge } from 'rxjs/operators';

operators导入的是instance method,似乎可以解决您的问题。

答案 1 :(得分:0)

import { merge } from 'rxjs/operators';

不建议使用合并:不建议使用静态合并。 (已弃用)版本rxjs6