我可以在 ReactAdmin 应用栏中显示过滤器设置吗?
Can I display filter settings in the ReactAdmin app bar?
是否可以在 ReactAdmin 应用栏中显示我当前过滤器的元素?
例如我有一个团队过滤器,用于显示公司中给定团队的销售结果。这一点都在工作。过滤器最终作为团队 ID 而不是名称出现在路由中。我不确定是否有可能改变它,而且我可能也不想这样做;但我还是想在应用栏的过滤器中显示所选团队 name。
我已经设置了自定义应用栏,但我需要的信息似乎无法作为应用栏的道具提供。
我可以在 Redux Tools 中看到,在 admin\resources
下,已按 id 预加载了团队;但我不确定这些预加载项目的布局是否得到官方支持?也没有关于何时加载它们的官方时间? (These must be there because they were loaded for the filter, so logically I guess(??) that the one I need must be there when a filter value has been selected....)
然后,据我所知,要获得当前的过滤器设置,我还必须从状态的 router
部分提取内容。
我可以尝试将我的自定义应用程序栏连接到 Redux 并提取上述项目。我想我可以让它工作 - 但它有强烈的代码味道。 'will break with any ReactAdmin updates'的味道,或许还夹杂着'accessing state from the wrong place, at the wrong time'!
的味道
是否有更简洁、更正式的方式来解决这个问题?
我已经实施了我在自己的问题中建议的 'not officially supported' 方法。它工作正常,但是 - 公平警告 - 据我所知它可能会在更新 ReactAdmin 后停止工作。
如果我想出了一个更受官方支持的方法,或者如果我设法将此中的任何内容提交回 ReactAdmin 项目,我将更新此答案。
所以,这是一个自定义布局:
// CustomLayout.js
import React from 'react';
import { connect } from 'react-redux';
import { Layout, AppBar } from 'react-admin';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import getFilterValue from './getFilterValue';
const useStyles = makeStyles(
theme => ({
title: {
flex: 1,
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
},
}),
{ name: 'RaAppBar' }
);
const CustomAppBarUnconnected = (props) => {
const classes = useStyles(props);
const { title } = props;
return (
<AppBar
{...props}
>
<Typography
variant="h6"
color="inherit"
className={classes.title}
>
{ title }
</Typography>
</AppBar>
);
}
const mapStateToProps = (state, props) => {
let team = getFilterValue(state, 'teamId', 'teams'); //, 'name');
let previousMonth = getFilterValue(state, 'previousMonth');
let title = `${team ? team.name : 'Company'} Sales. ${previousMonth ? `Previous month = ${previousMonth}` : 'Nothing to see here'}.`;
return {
...props,
title
};
};
const CustomAppBar = connect(
mapStateToProps,
)(CustomAppBarUnconnected);
export const CustomLayout = (props) =>
<Layout
{...props}
appBar={ CustomAppBar }
/>;
使用 <Admin layout={CustomLayout}>
在您的 ReactAdmin 应用程序中应用它。这是一些示例输出:
大多数自定义布局只是获得自定义应用栏所需的样板,它看起来像默认应用栏:它将 children 传递给标准 AppBar,应用所需的格式使标题看起来像标准标题。
If you want the default title to appear along with your custom title, add <span id="react-admin-title" />
where you want it to appear (presumably, somewhere next to { title }
).
If you also want to more thoroughly re-arrange the app bar then (following the ReactAdmin documentation), you would need to make a new custom AppBar class from scratch, starting from the original ReactAdmin AppBar class. Then just link it to Redux as I have done above.
此自定义布局的关键变化是 AppBar 现在连接到 Redux,这意味着在 mapStateToProps
中我们可以调用新功能 getFilterValue
:
// getFilterValue.js
const getFilterValue = (state, source, resource, field) => {
let value = undefined;
if (!state || !source) return value;
const filterJSON =
state.router &&
state.router.location &&
state.router.location.query &&
state.router.location.query.filter;
if (filterJSON) {
let filter = JSON.parse(decodeURIComponent(filterJSON));
let id = filter && filter[source];
if (id !== undefined) {
if (!resource) {
value = id;
} else {
const data =
state.admin &&
state.admin.resources &&
state.admin.resources[resource] &&
state.admin.resources[resource].data;
if (data) {
value = data[id];
if (field) {
value = value[field];
}
}
}
}
}
return value;
};
export default getFilterValue;
根据您传递给 getFilterValue
的参数,您可以:
- 从过滤器中获取原始项目:
(state, source)
- 将过滤器中的原始项目 ID 映射到已从 API 中获取的 object:
(state, source, resource)
- 将过滤器中的 id 映射到一个项目,然后从该项目中提取一个命名字段:
(state, source, resource, field)
undefined
如果要求的值不存在,总是返回;例如如果您不在包含所请求过滤器的页面上,或者如果用户尚未应用该过滤器,或者如果您在任何参数中输入错误。
是否可以在 ReactAdmin 应用栏中显示我当前过滤器的元素?
例如我有一个团队过滤器,用于显示公司中给定团队的销售结果。这一点都在工作。过滤器最终作为团队 ID 而不是名称出现在路由中。我不确定是否有可能改变它,而且我可能也不想这样做;但我还是想在应用栏的过滤器中显示所选团队 name。
我已经设置了自定义应用栏,但我需要的信息似乎无法作为应用栏的道具提供。
我可以在 Redux Tools 中看到,在 admin\resources
下,已按 id 预加载了团队;但我不确定这些预加载项目的布局是否得到官方支持?也没有关于何时加载它们的官方时间? (These must be there because they were loaded for the filter, so logically I guess(??) that the one I need must be there when a filter value has been selected....)
然后,据我所知,要获得当前的过滤器设置,我还必须从状态的 router
部分提取内容。
我可以尝试将我的自定义应用程序栏连接到 Redux 并提取上述项目。我想我可以让它工作 - 但它有强烈的代码味道。 'will break with any ReactAdmin updates'的味道,或许还夹杂着'accessing state from the wrong place, at the wrong time'!
的味道是否有更简洁、更正式的方式来解决这个问题?
我已经实施了我在自己的问题中建议的 'not officially supported' 方法。它工作正常,但是 - 公平警告 - 据我所知它可能会在更新 ReactAdmin 后停止工作。
如果我想出了一个更受官方支持的方法,或者如果我设法将此中的任何内容提交回 ReactAdmin 项目,我将更新此答案。
所以,这是一个自定义布局:
// CustomLayout.js
import React from 'react';
import { connect } from 'react-redux';
import { Layout, AppBar } from 'react-admin';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import getFilterValue from './getFilterValue';
const useStyles = makeStyles(
theme => ({
title: {
flex: 1,
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
},
}),
{ name: 'RaAppBar' }
);
const CustomAppBarUnconnected = (props) => {
const classes = useStyles(props);
const { title } = props;
return (
<AppBar
{...props}
>
<Typography
variant="h6"
color="inherit"
className={classes.title}
>
{ title }
</Typography>
</AppBar>
);
}
const mapStateToProps = (state, props) => {
let team = getFilterValue(state, 'teamId', 'teams'); //, 'name');
let previousMonth = getFilterValue(state, 'previousMonth');
let title = `${team ? team.name : 'Company'} Sales. ${previousMonth ? `Previous month = ${previousMonth}` : 'Nothing to see here'}.`;
return {
...props,
title
};
};
const CustomAppBar = connect(
mapStateToProps,
)(CustomAppBarUnconnected);
export const CustomLayout = (props) =>
<Layout
{...props}
appBar={ CustomAppBar }
/>;
使用 <Admin layout={CustomLayout}>
在您的 ReactAdmin 应用程序中应用它。这是一些示例输出:
大多数自定义布局只是获得自定义应用栏所需的样板,它看起来像默认应用栏:它将 children 传递给标准 AppBar,应用所需的格式使标题看起来像标准标题。
If you want the default title to appear along with your custom title, add
<span id="react-admin-title" />
where you want it to appear (presumably, somewhere next to{ title }
).If you also want to more thoroughly re-arrange the app bar then (following the ReactAdmin documentation), you would need to make a new custom AppBar class from scratch, starting from the original ReactAdmin AppBar class. Then just link it to Redux as I have done above.
此自定义布局的关键变化是 AppBar 现在连接到 Redux,这意味着在 mapStateToProps
中我们可以调用新功能 getFilterValue
:
// getFilterValue.js
const getFilterValue = (state, source, resource, field) => {
let value = undefined;
if (!state || !source) return value;
const filterJSON =
state.router &&
state.router.location &&
state.router.location.query &&
state.router.location.query.filter;
if (filterJSON) {
let filter = JSON.parse(decodeURIComponent(filterJSON));
let id = filter && filter[source];
if (id !== undefined) {
if (!resource) {
value = id;
} else {
const data =
state.admin &&
state.admin.resources &&
state.admin.resources[resource] &&
state.admin.resources[resource].data;
if (data) {
value = data[id];
if (field) {
value = value[field];
}
}
}
}
}
return value;
};
export default getFilterValue;
根据您传递给 getFilterValue
的参数,您可以:
- 从过滤器中获取原始项目:
(state, source)
- 将过滤器中的原始项目 ID 映射到已从 API 中获取的 object:
(state, source, resource)
- 将过滤器中的 id 映射到一个项目,然后从该项目中提取一个命名字段:
(state, source, resource, field)
undefined
如果要求的值不存在,总是返回;例如如果您不在包含所请求过滤器的页面上,或者如果用户尚未应用该过滤器,或者如果您在任何参数中输入错误。