1

我需要一个简单的 Angular-in-memory-web-api 分页。现在我有:

import { InMemoryDbService } from 'angular-in-memory-web-api';    

export class InMemoryDataService implements InMemoryDbService {    
    createDb() {
        const comments = [
            {
                'user': 'User 1',
                'comment': 'Praesent ac ipsum mattis, consectetur leo sed, faucibus urna.'
            },
            {
                'user': 'User 2',
                'comment': 'Integer consectetur ex eu tincidunt laoreet.'
            },
            {
                'user': 'User 1',
                'comment': 'Curabitur et mi pretium, varius diam in, aliquet ante.'
            },
            {
                'user': 'User 2',
                'comment': 'Sed id quam sed est hendrerit malesuada sed accumsan eros.'
            },
            {
                'user': 'User 2',
                'comment': 'Vivamus iaculis est nec lorem maximus, sed euismod libero faucibus.'
            },
            {
                'user': 'User 1',
                'comment': 'Quisque placerat mauris vel ligula faucibus cursus.'
            },
            {
                'user': 'User 2',
                'comment': 'Nullam ultrices velit ut enim iaculis, ac pretium lorem dictum.'
            }
        ];

        return { comments };    
    }
}

我可以使用('api/comments'). ('api/comments?per_page=5')在数据结束之前,我需要一个类似或类似的分页。谢谢

4

2 回答 2

0

我不知道您是否设法解决了这个问题,但不幸的是 angular-in-memory-web-api 不支持分页。你必须自己重写 GET 方法并做一些技巧来让它工作。

这是我的解决方案。这是我InMemoryDbService实现的一个片段。我的解决方案假设您在 url 中使用offsetlimit查询参数,并返回封装的数据,以及一些关于总数的元信息(这样您就知道有多少页)。

如您所见,它包含相当多的代码。那是因为我必须重写 angular-in-memory-web-api 通常为我处理的部分逻辑,比如过滤除offsetand之外的其他查询参数limit等。所以我复制了它的一些内部代码。

  // HTTP GET interceptor to support offset and limit query parameters
  get(reqInfo: RequestInfo) {
    if (reqInfo.query.has('offset') && reqInfo.query.has('limit') && reqInfo.collection) {
      const offset = +reqInfo.query.get('offset')[0];
      const limit = +reqInfo.query.get('limit')[0];

      // Remove offset and limit from query parameters so they're not considered as filtering parameters for the
      // collection later on.
      reqInfo.query.delete('offset');
      reqInfo.query.delete('limit');

      return reqInfo.utils.createResponse$(() => {
        const collection = reqInfo.collection as Array<{id: any}>;

        let meta: any;
        let data: any;
        if (reqInfo.id) {
          data = reqInfo.utils.findById(collection, reqInfo.id);
        } else {
          const filteredCollection = InMemoryDataService.applyQuery(collection, reqInfo.query);
          const totalCount = filteredCollection.length;
          meta = { totalCount };
          console.log(`offset: ${offset}, limit: ${limit}`);
          data = filteredCollection.slice(offset, offset + limit);
          console.log(`Total count: ${totalCount}, and returned data count: ${data.length}`);
        }

        const options: ResponseOptions = data ?
        {
          body: { meta, data },
          status: STATUS.OK
        } :
        {
          body: { error: `'${reqInfo.collectionName}' with id='${reqInfo.id}' not found` },
          status: STATUS.NOT_FOUND
        };
        return InMemoryDataService.finishOptions(options, reqInfo);
      });
    } else {
      return undefined;
    }
  }

  private static finishOptions(options: ResponseOptions, {headers, url}: RequestInfo) {
    options.statusText = getStatusText(options.status);
    options.headers = headers;
    options.url = url;

    return options;
  }

  private static applyQuery(collection: Array<object>, query: Map<string, string[]>) {
    // extract filtering conditions - {propertyName, RegExps) - from query/search parameters
    const conditions = [];
    query.forEach((values, key) => {
        values.forEach(value => { conditions.push({ key, rx: new RegExp(decodeURI(value), 'i') }); });
    });
    const len = conditions.length;
    if (!len) {
        return collection;
    }
    // AND the RegExp conditions
    return collection.filter(row => {
        let ok = true;
        let i = len;
        while (ok && i) {
            i -= 1;
            const cond = conditions[i];
            ok = cond.rx.test(row[cond.name]);
        }
        return ok;
    });
  }
于 2019-11-08T15:37:02.780 回答
0

我不认为 angular-in-memory-web-api 有这个功能。您可以创建一个这样做的服务,例如:

import { EventEmitter, Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map, skip, take } from 'rxjs/operators';

// the interface of your comments
import { IComment } from 'app/models';

@Injectable()
export class CommentsService{

    resourceUrl : string = 'api/comments';

    constructor(
        private http : HttpClient
    ){}

    getComments(params? : any) : Observable<IComment[]>{
        const {perPage, page} = params;
        return this.http.get<IComment[]>(this.resourceUrl).pipe(
            map((result : IComment[]) => {
                // you need to sort, if your data was not sorted
                return result.sort((a : IComment, b: IComment) => {
                    if(a.timestamp > b.timestamp) return 1;
                    if(a.timestamp < b.timestamp) return -1;
                    return 0;
                }).slice(perPage*page, perPage);
           })
        );
    }
}

这只是一个想法。

于 2018-05-08T10:46:30.147 回答