在 React-Admin 仪表板上使用 <List />
Use <List /> on React-Admin dashboard
我正在使用带有自定义仪表板组件的 react-admin v2.3.2,如 react-admin 教程中所示。
<Admin dashboard={MyDashboard}>
<Resource name="incidents ... />
</Admin>
现在我想使用 react-admin 组件在我的仪表板上显示事件列表,但 react-admin 抱怨缺少 'hasEdit'.
等属性
我只是将仪表板组件的 props 传递给了 List,但这显然不起作用:
class MyDashboard extends React.Component {
constructor(props) {
super(props)
render(
return <List {...this.props}>
<Datagrid> .... </Datagrid>
</List>
)
}
是否可以在仪表板上使用 react-admin 的 <List />
组件?如果可以,如何实现?
提前致谢,
托马斯
您一定想显示来自各种资源的数据,否则您只需使用常规 "List" 页面即可。
仪表板可以做到这一点。看看演示 Dashboard
您传递给组件的多个 dataProvider(GET_LIST,...。您可以使用此演示仪表板组件作为示例。Pending Orders
我终于通过伪造所需的道具成功地使用了 react-admin 的组件。在 MyDashboard 组件中,我定义了组件所需的道具:
let fakeProps = {
basePath: "/incidents",
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
history: {},
location: { pathname: "/", search: "", hash: "", state: undefined },
match: { path: "/", url: "/", isExact: true, params: {} },
options: {},
permissions: null,
resource: "incidents"
}
<List {...fakeProps}>
<DataGrid>
<TextField .... />
</DataGrid>
</List>
这确实是一个次优的解决方案,但在第一个 运行 它解决了我的问题。
我们收到了在仪表板中创建列表的请求,因此我使用了已接受的答案。虽然分页不会触发对服务器的新请求,即使 url 正在更改。
这是使用 react-router v4 进行分页的最终解决方案。
在<Admin dashboard={Dashboard}>
我补充说:
<Resource name="dashboard-stats"/>
在 Dashboard.js 中,这是我拥有的:
import React, { Component } from 'react';
import { GET_LIST } from 'react-admin';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import dataProvider from './dataProvider';
import {
List,
TextField,
Datagrid
} from 'react-admin';
export default class Dashboard extends Component {
state = {};
initProps = {
basePath: "/",
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
location: { pathname: "/", search: "", hash: "", state: undefined },
match: { path: "/", url: "/", isExact: true, params: {} },
options: {
},
permissions: null,
resource: "dashboard-stats",
perPage: 5
};
componentWillMount() {
this.unlisten = this.props.history.listen((location, action) => {
if (location.search) {
//regex from:
let queryParams = JSON.parse('{"' + decodeURI(location.search).replace(/"/g, '\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
let perPage = queryParams.perPage;
let page = queryParams.page;
this.initProps.perPage = perPage;
this.initProps.page = page;
this.initProps.location = location;
this.setState({'initProps': this.initProps})
}
});
}
componentWillUnmount() {
this.unlisten();
}
componentDidMount() {
this.setState({'initProps': this.initProps});
dataProvider(GET_LIST, 'stats', {
sort: { field: 'date', order: 'DESC' },
pagination: { page: 1, perPage: 50 },
})
.then(response => {
this.setState({'stats': response.data});
});
}
render() {
const {
initProps
} = this.state;
if(!initProps) {
return false;
}
return <Card>
<CardHeader title="Welcome to the Dashboard" />
<List {...initProps} >
<Datagrid>
<TextField source="description" />
<TextField source="state" />
<TextField source="date" />
</Datagrid>
</List>
</Card>;
}
}
不要忘记用刚刚更改的位置更新位置 this.initProps.location
- 否则它将在第一次点击(路线更改)时起作用,然后它将停止工作
感谢您的解决方案。屏幕呈现以下警告
如何删除所有警告?
警告:React 无法识别 DOM 元素上的 basePath
属性。如果您有意希望它作为自定义属性出现在 DOM 中,请将其拼写为小写 basepath
。如果您不小心从父组件传递了它,请将其从 DOM 元素中移除。
像 basePath 控制台显示与其他道具相同的警告 "currentSort, defaultTitle, displayedFilters,filterValues,hasCreate,hideFilter,isLoading,loadedOnce,onToggleItem,onUnselectItems,perPage,selectedIds,setFilters,setPage,setPerPage,setSort,showFilter,hasBulkActions"
警告:标签上的属性 translate
的值无效。要么将它从元素中移除,要么传递一个字符串或数字值以将其保留在 DOM 中。详情
const initProps = {
basePath: '/',
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
location: { pathname: '/', search: '', hash: '', state: undefined },
match: { path: '/', url: '/', isExact: true, params: {} },
options: {},
permissions: null,
resource: 'dashboard',
perPage: 5
};
<List
{...initProps}
filterDefaultValues={{
arrivedTimestampStart: moment().format('YYYY-MM-DD'),
arrivedTimestamp: moment().format('YYYY-MM-DD')
}}
filters={<DashboardFilter />}
sort={{ field: 'arrivedTimestamp', order: 'DESC' }}
pagination={<Fragment />}
exporter={false}
>
<Responsive
medium={
<div style={styles.flex}>
<OtherComponent />
</div>
}
/>
</List>
我在研究类似内容时发现了这个页面。
现在(2020 年底)执行此操作的方法是在页面上为要在仪表板上显示的主要资源创建一个 ListContextProvider,以便您获得该上下文提供的所有内容,包括过滤器。
const controllerProps = useListController(props);
<ListContextProvider value={controllerProps}>
<MyDashboardView>
</ListContextProvider>
我认为 v4+ 中的答案现在是 useList
挂钩,您可以在列表文档页面上看到它:https://marmelab.com/react-admin/List.html。从该页面复制:
const data = [
{ id: 1, name: 'Arnold' },
{ id: 2, name: 'Sylvester' },
{ id: 3, name: 'Jean-Claude' },
]
const ids = [1, 2, 3];
const MyComponent = () => {
const listContext = useList({
data,
ids,
basePath: '/resource',
resource: 'resource',
});
return (
<ListContextProvider value={listContext}>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
</Datagrid>
</ListContextProvider>
);
};
我正在使用带有自定义仪表板组件的 react-admin v2.3.2,如 react-admin 教程中所示。
<Admin dashboard={MyDashboard}>
<Resource name="incidents ... />
</Admin>
现在我想使用 react-admin 组件在我的仪表板上显示事件列表,但 react-admin 抱怨缺少 'hasEdit'.
等属性我只是将仪表板组件的 props 传递给了 List,但这显然不起作用:
class MyDashboard extends React.Component {
constructor(props) {
super(props)
render(
return <List {...this.props}>
<Datagrid> .... </Datagrid>
</List>
)
}
是否可以在仪表板上使用 react-admin 的 <List />
组件?如果可以,如何实现?
提前致谢, 托马斯
您一定想显示来自各种资源的数据,否则您只需使用常规 "List" 页面即可。
仪表板可以做到这一点。看看演示 Dashboard
您传递给组件的多个 dataProvider(GET_LIST,...。您可以使用此演示仪表板组件作为示例。Pending Orders
我终于通过伪造所需的道具成功地使用了 react-admin 的组件。在 MyDashboard 组件中,我定义了组件所需的道具:
let fakeProps = {
basePath: "/incidents",
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
history: {},
location: { pathname: "/", search: "", hash: "", state: undefined },
match: { path: "/", url: "/", isExact: true, params: {} },
options: {},
permissions: null,
resource: "incidents"
}
<List {...fakeProps}>
<DataGrid>
<TextField .... />
</DataGrid>
</List>
这确实是一个次优的解决方案,但在第一个 运行 它解决了我的问题。
我们收到了在仪表板中创建列表的请求,因此我使用了已接受的答案。虽然分页不会触发对服务器的新请求,即使 url 正在更改。
这是使用 react-router v4 进行分页的最终解决方案。
在<Admin dashboard={Dashboard}>
我补充说:
<Resource name="dashboard-stats"/>
在 Dashboard.js 中,这是我拥有的:
import React, { Component } from 'react';
import { GET_LIST } from 'react-admin';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import dataProvider from './dataProvider';
import {
List,
TextField,
Datagrid
} from 'react-admin';
export default class Dashboard extends Component {
state = {};
initProps = {
basePath: "/",
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
location: { pathname: "/", search: "", hash: "", state: undefined },
match: { path: "/", url: "/", isExact: true, params: {} },
options: {
},
permissions: null,
resource: "dashboard-stats",
perPage: 5
};
componentWillMount() {
this.unlisten = this.props.history.listen((location, action) => {
if (location.search) {
//regex from:
let queryParams = JSON.parse('{"' + decodeURI(location.search).replace(/"/g, '\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
let perPage = queryParams.perPage;
let page = queryParams.page;
this.initProps.perPage = perPage;
this.initProps.page = page;
this.initProps.location = location;
this.setState({'initProps': this.initProps})
}
});
}
componentWillUnmount() {
this.unlisten();
}
componentDidMount() {
this.setState({'initProps': this.initProps});
dataProvider(GET_LIST, 'stats', {
sort: { field: 'date', order: 'DESC' },
pagination: { page: 1, perPage: 50 },
})
.then(response => {
this.setState({'stats': response.data});
});
}
render() {
const {
initProps
} = this.state;
if(!initProps) {
return false;
}
return <Card>
<CardHeader title="Welcome to the Dashboard" />
<List {...initProps} >
<Datagrid>
<TextField source="description" />
<TextField source="state" />
<TextField source="date" />
</Datagrid>
</List>
</Card>;
}
}
不要忘记用刚刚更改的位置更新位置 this.initProps.location
- 否则它将在第一次点击(路线更改)时起作用,然后它将停止工作
感谢您的解决方案。屏幕呈现以下警告
如何删除所有警告?
警告:React 无法识别 DOM 元素上的 basePath
属性。如果您有意希望它作为自定义属性出现在 DOM 中,请将其拼写为小写 basepath
。如果您不小心从父组件传递了它,请将其从 DOM 元素中移除。
像 basePath 控制台显示与其他道具相同的警告 "currentSort, defaultTitle, displayedFilters,filterValues,hasCreate,hideFilter,isLoading,loadedOnce,onToggleItem,onUnselectItems,perPage,selectedIds,setFilters,setPage,setPerPage,setSort,showFilter,hasBulkActions"
警告:标签上的属性 translate
的值无效。要么将它从元素中移除,要么传递一个字符串或数字值以将其保留在 DOM 中。详情
const initProps = {
basePath: '/',
hasCreate: false,
hasEdit: false,
hasList: true,
hasShow: false,
location: { pathname: '/', search: '', hash: '', state: undefined },
match: { path: '/', url: '/', isExact: true, params: {} },
options: {},
permissions: null,
resource: 'dashboard',
perPage: 5
};
<List
{...initProps}
filterDefaultValues={{
arrivedTimestampStart: moment().format('YYYY-MM-DD'),
arrivedTimestamp: moment().format('YYYY-MM-DD')
}}
filters={<DashboardFilter />}
sort={{ field: 'arrivedTimestamp', order: 'DESC' }}
pagination={<Fragment />}
exporter={false}
>
<Responsive
medium={
<div style={styles.flex}>
<OtherComponent />
</div>
}
/>
</List>
我在研究类似内容时发现了这个页面。 现在(2020 年底)执行此操作的方法是在页面上为要在仪表板上显示的主要资源创建一个 ListContextProvider,以便您获得该上下文提供的所有内容,包括过滤器。
const controllerProps = useListController(props);
<ListContextProvider value={controllerProps}>
<MyDashboardView>
</ListContextProvider>
我认为 v4+ 中的答案现在是 useList
挂钩,您可以在列表文档页面上看到它:https://marmelab.com/react-admin/List.html。从该页面复制:
const data = [
{ id: 1, name: 'Arnold' },
{ id: 2, name: 'Sylvester' },
{ id: 3, name: 'Jean-Claude' },
]
const ids = [1, 2, 3];
const MyComponent = () => {
const listContext = useList({
data,
ids,
basePath: '/resource',
resource: 'resource',
});
return (
<ListContextProvider value={listContext}>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
</Datagrid>
</ListContextProvider>
);
};