React Admin - 如何使用嵌套路径调用dataProvider,如abc / def

时间:2018-05-18 15:19:59

标签: admin-on-rest react-admin

React-admin的Resource组件将name prop值映射到端点。

E.g。从中访问数据。 http://example.com/abc,您的Resource组件如下所示: <Resource name='abc'/>

我想在http://example.com/abc/def访问资源? 此<Resource name='abc/def'/>甚至不会调用dataProvider函数。

我不想最终得到丑陋的解决方案,如:

// App.js
<Resource name='def'/>
// dataProvider.js
if (resource==='def') {
url = 'abc/def'
}

资源名称是否必须没有/?任何黑客?

2 个答案:

答案 0 :(得分:1)

由于我们的api并不是严格意义上的,所以我正在一个项目中,最终我们编写了自己的dataProvider。

把头缠起来有点像皮塔饼,但是一旦弄清楚了工作流程,还算不错。

基本上,在调用dataProvider时会发生三件事

  1. dataProvider使用这些参数来调用convertDataProviderRequestToHTTP,它返回一个URL和用于发送fetch / api调用(构建请求)的选项
  2. 获取请求/ api调用已发送(发送请求)
  3. dataProvider返回调用convertHTTPResponseToDataProvider的结果,该转换将响应转换为对接收它的资源有用的内容(处理来自请求的响应)

这里是react-admin文档相关部分的链接 https://marmelab.com/react-admin/DataProviders.html#writing-your-own-data-provider

我们的解决方案使用大小为类型的switch语句,然后每种情况都有处理不同资源的逻辑。

我不确定这是否是预期的实现,但最终却得到了这样的东西:

// import all the things

// set your api path prefix

const convertDataProviderRequestToHTTP = (type, resource, params) => {
     //switch statement with one case for each action type
     // and some logic where necessary for different resources ie. 
    switch(type){
        case "GET_ONE":{
            // if statements to handle resources with goofy endpoints
            if(resource === 'abc/def'){
                const url = `${API_PREFIX}/abc/def`;
                const options = {
                    // set the specific options that you need for a 
                    // each particular resource
                }
            }

            // handles resources with normal restful endpoints
            const url = `${API_PREFIX}/${RESOURCE}`;
            const options = {
                // this part depends on how you're doing your fetching
                // might need to include the particular rest verb
                // and any other settings
            }
        }

    }
    return {
        url,
        options
    }

}

const convertHTTPResponseToDataProvider = (response, type, resource, params){
    // another switch statement that converts the response that you get
    // from your api to something that's useful to your Resource
    switch(type){
        case 'GET_ONE':{
            if(resource === 'abc/def'){
                // convert response into something useful and return it
                return{
                      data: convertedResponse
                }
            }
        }
    }
}

export default (type, resource, params) => {

    // this comes from react-admin, you could use plain old fetch or
    // your favorite fetch library like axios instead
    const { fetchJson } = fetchUtils;

    // part 1, using the stuff that was sent in the dataProvider 
    // call to generate what you need to sending your fetch
    const { url, options } = convertDataProviderRequestToHTTP(
        type,
        resource,
        params
    );

    // add logic for grabbing your tokens and adding headers to options here
    options.headers.set('headerkey', 'headervalue');

    // part 2 sending the fetch request
    return fetchJson(url, options).then(response =>
        // part 3, converting the response and returning it
        convertHTTPResponseToDataProvider(response, type, resource, params)
    );
};

随着该应用程序的发展,我们最终将其分解为单独的文件,因此更易于阅读,但到目前为止看来对我们来说还可以。

我必须安装redux浏览器工具,并插入许多日志记录语句以逐步完成该过程,并更好地了解发生了什么以及何时发生。在获得第一个动作类型/资源组合后,就可以轻松地将其单击并添加到该动作中。

答案 1 :(得分:0)

我不知道您是否仍需要此功能,但我也无法使用嵌套路径。

我发现我使用的是函数而不是箭头函数。

所以不要使用

function AdminPage(props) {
 return (
  <Admin dataProvider={dataProvider}>
    <Resource name="abc/def" list={ListGuesser} />
  </Admin>
 );
}

使用:

const AdminPage = (props) => {
 return (
  <Admin dataProvider={dataProvider}>
    <Resource name="abc/def" list={ListGuesser} />
  </Admin>
 );
};

然后它应该起作用!