Angular Material Table - 映射服务器响应以满足DataSource合同

问题描述 投票:2回答:1

我正在组合一个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)
angular observable material
1个回答
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;
  }

}

奖金:

您应该使用http选项,而不是插入网址:

this.http.get(url, {
  headers: this.getHeaders(),
  params: {
    queryString: queryString,
    startIndex: startIndex,
    count: count
  }
});

此外,服务名称中还有一个小错字:

IntelienceService => IntelligenceService
© www.soinside.com 2019 - 2024. All rights reserved.