У меня есть функция поиска, которая была написана в 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-м const внутри трубы:
merge(searchSource),
с ошибкой:
Аргумент типа «Наблюдаемый» не присваивается
параметр типа 'OperatorFunction'.
Тип «Наблюдаемый» не соответствует подписи
'(источник: наблюдаемый): наблюдаемый <{}>'
что я вроде понимаю (это несоответствие параметров, потому что в rxjs6 мы должны использовать OperatorFunctions), но я понятия не имею, как это исправить.
EDIT
Это поисковая служба (для 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
}