Angular 6 & rxjs6 - 管道运算符 - 类型 'Observable<>' 不提供签名匹配
Angular 6 & rxjs6 - piped operators - Type 'Observable<>' provides no match for the signature
我有一个搜索功能,在版本 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 抱怨管道内第三个常量中的这一行:
merge(searchSource),
错误:
Argument of type 'Observable' is not assignable to
parameter of type 'OperatorFunction'.
Type 'Observable' provides no match for the signature
'(source: Observable): Observable<{}>'
我有点理解(这是一个参数不匹配,因为在 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
}
你只需要改变导入,它实际上应该是:
import { merge } from 'rxjs/operators';
从 operators
导入的是 instance method,似乎可以解决您的问题。
import { merge } from 'rxjs/operators';
合并已弃用:弃用以支持静态合并。 (弃用)版本 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 抱怨管道内第三个常量中的这一行:
merge(searchSource),
错误:
Argument of type 'Observable' is not assignable to parameter of type 'OperatorFunction'.
Type 'Observable' provides no match for the signature '(source: Observable): Observable<{}>'
我有点理解(这是一个参数不匹配,因为在 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
}
你只需要改变导入,它实际上应该是:
import { merge } from 'rxjs/operators';
从 operators
导入的是 instance method,似乎可以解决您的问题。
import { merge } from 'rxjs/operators';
合并已弃用:弃用以支持静态合并。 (弃用)版本 rxjs6