代码之家  ›  专栏  ›  技术社区  ›  rmcsharry

Angular 6&rxjs6-管道运算符-类型“observeable<>”不提供与签名匹配的结果

  •  0
  • rmcsharry  · 技术社区  · 6 年前

    在Angular版本6之前,我有一个这样编写的搜索函数:

    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在管道内部的第3个常量中抱怨这条管线:

    merge(searchSource),
    

    “Observable”类型的参数不可赋值给 “OperatorFunction”类型的参数。

    类型“Observable”与签名不匹配 '(来源:Observable):Observable<{}>'


    编辑

    这是搜索服务(对于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
    }
    
    1 回复  |  直到 6 年前
        1
  •  5
  •   user184994    6 年前

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

    import { merge } from 'rxjs/operators';
    

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

        2
  •  0
  •   Tom    5 年前

    import { merge } from 'rxjs/operators';