我正在组合一个Angular Material Table来显示从服务器返回的结果。数据结构如下:
export class Question
{
question : string;
anonymous : boolean;
}
export class SearchResult
{
totalCount : number;
pageBeginIndex : number;
pageSize : number;
questions : Question[];
}
http get包含在一个计算为observable的函数中:
public getSearchQuestions = (queryString : string, startIndex : number, count : number): Observable<SearchResult> =>
{
let url = this.baseUrl + "search?queryString=" + queryString + "&startIndex=" + startIndex + "&count=" + count;
return this.http.get(url, { headers : this.getHeaders() })
.map(response => response.json() as SearchResult)
.catch(error => this.handleError(error));
}
我遇到挑战的那一点是Table的DataSource定义中的connect()函数。典型的示例显示了一个函数的返回,该函数直接从服务器评估到Observable []获取结果。我的情况更复杂,因为我需要通过http get函数提取Observable返回,这是DataSource :: connect()契约所需的Observable的包装器。我不想在http get数据映射中进行这种解包,因为我还需要同时提取DataSource中的totalCount字段。这是我必须去的地方:
export class SearchDataSource extends DataSource<any>
{
recordCount : number;
constructor(private service: IntelienceService, private searchQuery : string, private _paginator: MatPaginator) {
super();
}
connect(): Observable<Question[]> {
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
return Observable.create((observer) : Observable<Question[]> => {
return this.service.getSearchQuestions(this.searchQuery, startIndex, this._paginator.pageSize).map(
searchResult => {
// Execution never reaches here
this.recordCount = searchResult.totalCount;
return searchResult.questions },
error => { console.log('error') }
);
});
}
disconnect() { }
}
虽然这会编译Table的Paginator会抛出一个内部错误,表明从connect返回的值是未定义的 - 实际上执行永远不会达到上述代码中注释所指示的点。任何帮助,以了解如何创建一个新的Observable包装现有的Observable并以我指示的方式映射数据将非常感激。
===编辑===
我对这次修订有了进一步的了解:
connect(): Observable<SearchQuestion[]> {
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
return Observable.create(observer => {
this.service.getSearchQuestions(this.searchQuery, startIndex, this._paginator.pageSize).subscribe(
(searchResults) => {
observer.next(() => { return searchResults.questions; });
observer.complete();
},
error => { console.log('error') }
);
});
}
现在调用getSearchQuestions中的http get,但是没有调用observer.next()函数,并且paginator继续抛出未定义的错误:
ERROR TypeError: Cannot read property 'pageIndex' of undefined
at SearchDataSource.webpackJsonp.../../../../../src/app/search/search.component.ts.SearchDataSource.connect (search.component.ts:61)
答案 0 :(得分:2)
您根本不需要Observable.create()
。
startIndex
不应该是常量,每次翻页时都应该计算它。
export class SearchDataSource extends DataSource<Question> {
recordCount: number;
constructor(private intelienceService: IntelienceService,
private searchQuery: string,
private _paginator: MatPaginator) {
super();
}
connect(): Observable<Question[]> {
return this.intelienceService.getSearchQuestions(this.searchQuery, this.getStartIndex(), this._paginator.pageSize)
.map(searchResult => {
this.recordCount = searchResult.totalCount;
return searchResult.questions;
}, () => { console.log('error'); }
);
}
disconnect() {
// intentionally left blank
}
private getStartIndex(): number {
return this._paginator.pageIndex * this._paginator.pageSize;
}
}
<强>加成:强>
不应插入 url ,而应使用http选项:
this.http.get(url, {
headers: this.getHeaders(),
params: {
queryString: queryString,
startIndex: startIndex,
count: count
}
});
服务名称中也有一个小错字:
IntelienceService => IntelligenceService