React Admin中的默认排序、分页参数名称和逻辑不一致。

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

我有一个简单的前台react-admin应用程序,有一个Flask API,我试图在我的API中实现排序、过滤和分页。

我使用的是 ra-data-json-server 的数据提供器,而根据 本规格我必须用"_sort"、"_start "和"_end "参数(带下划线)来实现它。

然而,当我查看我的Front应用程序执行的GET查询时,排序和分页将是类似的东西。

https://balbla.com/#/users?filter=%7B%7D&order=ASC&page=1&perPage=10&sort=roles

这与文档中的内容是一致的 https:/marmelab.comreact-adminDataProviders.html。

所以我很困扰,因为

  • 参数名称不同(下划线)。
  • 分页逻辑是完全不同的(结束和开始与页码和页长)。

是我遗漏了什么,还是确实有不一致的地方?要实现哪一个?对我来说,最简单的是将我的后台调整为实际的Front查询格式,但这不是文档。

谢谢

react-admin
1个回答
1
投票

我一开始也有和你一样的困惑,后来我看到了ra-data-json-server的源代码。它实现了_sort,_order,_start & _end。首先,你需要在你的API中实现排序和分页。我将建议你使用下面这个ra-data-js-son-server数据提供者。

import { stringify } from "query-string";
import { fetchUtils } from "ra-core";
/**
 * Maps react-admin que`enter code here`ries to a json-server powered REST API
 *
 * @see https://github.com/typicode/json-server
 *
 * @example
 *
 * getList          => GET http://my.api.url/posts?_sort=title&_order=ASC&_start=0&_end=24
 * getOne           => GET http://my.api.url/posts/123
 * getManyReference => GET http://my.api.url/posts?author_id=345
 * getMany          => GET http://my.api.url/posts/123, GET http://my.api.url/posts/456, GET http://my.api.url/posts/789
 * create           => POST http://my.api.url/posts/123
 * update           => PUT http://my.api.url/posts/123
 * updateMany       => PUT http://my.api.url/posts/123, PUT http://my.api.url/posts/456, PUT http://my.api.url/posts/789
 * delete           => DELETE http://my.api.url/posts/123
 *
 * @example
 *
 * import React from 'react';
 * import { Admin, Resource } from 'react-admin';
 * import jsonServerProvider from 'ra-data-json-server';
 *
 * import { PostList } from './posts';
 *
 * const App = () => (
 *     <Admin dataProvider={jsonServerProvider('http://jsonplaceholder.typicode.com')}>
 *         <Resource name="posts" list={PostList} />
 *     </Admin>
 * );
 *
 * export default App;
 */
var __assign =
  (this && this.__assign) ||
  function () {
    __assign =
      Object.assign ||
      function (t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
      };
    return __assign.apply(this, arguments);
  };

export default (function (apiUrl, httpClient) {
  if (httpClient === void 0) {
    httpClient = fetchUtils.fetchJson;
  }
  return {
    getList: function (resource, params) {
      var _a = params.pagination,
        page = _a.page,
        perPage = _a.perPage;
      var _b = params.sort,
        field = _b.field,
        order = _b.order;
      var query = __assign(
        __assign({}, fetchUtils.flattenObject(params.filter)),
        {
          _sort: field,
          _order: order,
          _start: (page - 1) * perPage + 1,
          _end: page * perPage,
        }
      );
      var url = apiUrl + "/" + resource + "?" + stringify(query);
      return httpClient(url).then(function (_a) {
        var headers = _a.headers,
          json = _a.json;
        if (!headers.has("x-total-count")) {
          throw new Error(
            "The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?"
          );
        }
        return {
          data: json,
          total: parseInt(headers.get("x-total-count").split("/").pop(), 10),
        };
      });
    },
    getOne: function (resource, params) {
      return httpClient(apiUrl + "/" + resource + "/" + params.id).then(
        function (_a) {
          var json = _a.json;
          return {
            data: json,
          };
        }
      );
    },
    getMany: function (resource, params) {
      var query = {
        id: params.ids,
      };
      var url = apiUrl + "/" + resource + "?" + stringify(query);
      return httpClient(url).then(function (_a) {
        var json = _a.json;
        return { data: json };
      });
    },
    getManyReference: function (resource, params) {
      var _a;
      var _b = params.pagination,
        page = _b.page,
        perPage = _b.perPage;
      var _c = params.sort,
        field = _c.field,
        order = _c.order;
      var query = __assign(
        __assign({}, fetchUtils.flattenObject(params.filter)),
        ((_a = {}),
        (_a[params.target] = params.id),
        (_a._sort = field),
        (_a._order = order),
        (_a._start = (page - 1) * perPage),
        (_a._end = page * perPage),
        _a)
      );
      var url = apiUrl + "/" + resource + "?" + stringify(query);
      return httpClient(url).then(function (_a) {
        var headers = _a.headers,
          json = _a.json;
        if (!headers.has("x-total-count")) {
          throw new Error(
            "The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?"
          );
        }
        return {
          data: json,
          total: parseInt(headers.get("x-total-count").split("/").pop(), 10),
        };
      });
    },
    update: function (resource, params) {
      return httpClient(apiUrl + "/" + resource + "/" + params.id, {
        method: "PUT",
        body: JSON.stringify(params.data),
      }).then(function (_a) {
        var json = _a.json;
        return { data: json };
      });
    },
    // json-server doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
    updateMany: function (resource, params) {
      return Promise.all(
        params.ids.map(function (id) {
          return httpClient(apiUrl + "/" + resource + "/" + id, {
            method: "PUT",
            body: JSON.stringify(params.data),
          });
        })
      ).then(function (responses) {
        return {
          data: responses.map(function (_a) {
            var json = _a.json;
            return json.id;
          }),
        };
      });
    },
    create: function (resource, params) {
      return httpClient(apiUrl + "/" + resource, {
        method: "POST",
        body: JSON.stringify(params.data),
      }).then(function (_a) {
        var json = _a.json;
        return {
          data: __assign(__assign({}, params.data), { id: json.id }),
        };
      });
    },
    delete: function (resource, params) {
      return httpClient(apiUrl + "/" + resource + "/" + params.id, {
        method: "DELETE",
      }).then(function (_a) {
        var json = _a.json;
        return { data: json };
      });
    },
    // json-server doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
    deleteMany: function (resource, params) {
      return Promise.all(
        params.ids.map(function (id) {
          return httpClient(apiUrl + "/" + resource + "/" + id, {
            method: "DELETE",
          });
        })
      ).then(function (responses) {
        return {
          data: responses.map(function (_a) {
            var json = _a.json;
            return json.id;
          }),
        };
      });
    },
  };
});
© www.soinside.com 2019 - 2024. All rights reserved.