Loading...
Loading...
Compare original and translation side by side
getListgetOnecreateupdatedeletegetManygetManyReferenceupdateManydeleteManytranslatechangeLocalegetLocalefetchaxiosgetListgetOnecreateupdatedeletegetManygetManyReferenceupdateManydeleteManytranslatechangeLocalegetLocalefetchaxios<Edit actions={<MyCustomActions />}>
<SimpleForm>
<TextInput source="title" />
</SimpleForm>
</Edit><Admin layout={MyLayout}><Layout menu={MyMenu}><Edit actions={<MyCustomActions />}>
<SimpleForm>
<TextInput source="title" />
</SimpleForm>
</Edit><Admin layout={MyLayout}><Layout menu={MyMenu}>useRecordContext()useListContext()useShowContext()useEditContext()useCreateContext()useTranslate()useGetIdentity()useRecordContext()useListContext()useShowContext()useEditContext()useCreateContext()useTranslate()useGetIdentity()use*ControlleruseListController()useEditController()useShowController()use*ControlleruseListController()useEditController()useShowController()<Resource>/posts/posts/create/posts/:id/edit/posts/:id/show<CustomRoutes>useCreatePath()<Link>routerProvider<Resource>/posts/posts/create/posts/:id/edit/posts/:id/show<CustomRoutes>useCreatePath()<Link>routerProviderconst { data, total, isPending, error } = useGetList('posts', {
pagination: { page: 1, perPage: 25 },
sort: { field: 'created_at', order: 'DESC' },
filter: { status: 'published' },
});
const { data: record, isPending } = useGetOne('posts', { id: 123 });
const { data: records } = useGetMany('posts', { ids: [1, 2, 3] });
const { data, total } = useGetManyReference('comments', {
target: 'post_id', id: 123,
pagination: { page: 1, perPage: 25 },
});const { data, total, isPending, error } = useGetList('posts', {
pagination: { page: 1, perPage: 25 },
sort: { field: 'created_at', order: 'DESC' },
filter: { status: 'published' },
});
const { data: record, isPending } = useGetOne('posts', { id: 123 });
const { data: records } = useGetMany('posts', { ids: [1, 2, 3] });
const { data, total } = useGetManyReference('comments', {
target: 'post_id', id: 123,
pagination: { page: 1, perPage: 25 },
});[mutate, state]const [create, { isPending }] = useCreate();
const [update] = useUpdate();
const [deleteOne] = useDelete();
// Call with resource and params
create('posts', { data: { title: 'Hello' } });
update('posts', { id: 1, data: { title: 'Updated' }, previousData: record });
deleteOne('posts', { id: 1, previousData: record });[mutate, state]const [create, { isPending }] = useCreate();
const [update] = useUpdate();
const [deleteOne] = useDelete();
// 传入资源和参数调用
create('posts', { data: { title: 'Hello' } });
update('posts', { id: 1, data: { title: 'Updated' }, previousData: record });
deleteOne('posts', { id: 1, previousData: record });const authProvider = {
login: ({ username, password }) => Promise<void>,
logout: () => Promise<void>,
checkAuth: () => Promise<void>, // Verify credentials are valid
checkError: (error) => Promise<void>, // Detect auth errors from API responses
getIdentity: () => Promise<{ id, fullName, avatar }>,
getPermissions: () => Promise<any>,
canAccess: ({ resource, action, record }) => Promise<boolean>, // RBAC
};useGetIdentity()useCanAccess()<Authenticated>useAuthenticated()authProvider.canAccess()useCanAccess()httpClientconst authProvider = {
login: ({ username, password }) => Promise<void>,
logout: () => Promise<void>,
checkAuth: () => Promise<void>, // 验证凭证是否有效
checkError: (error) => Promise<void>, // 从API响应中检测身份验证错误
getIdentity: () => Promise<{ id, fullName, avatar }>,
getPermissions: () => Promise<any>,
canAccess: ({ resource, action, record }) => Promise<boolean>, // 基于角色的访问控制(RBAC)
};useGetIdentity()useCanAccess()<Authenticated>useAuthenticated()authProvider.canAccess()useCanAccess()httpClient{/* Show a the company of the current record based on its company_id */}
<ReferenceField source="company_id" reference="companies" />
{/* Show a list of related records (reverse FK) */}
<ReferenceManyField reference="comments" target="post_id">
<DataTable>
<TextField source="body" />
<DateField source="created_at" />
</DataTable>
</ReferenceManyField>
{/* Show multiple referenced records (array of IDs) */}
<ReferenceArrayField source="tag_ids" reference="tags">
<SingleFieldList>
<ChipField source="name" />
</SingleFieldList>
</ReferenceArrayField>{/* 根据当前记录的company_id显示对应的公司 */}
<ReferenceField source="company_id" reference="companies" />
{/* 显示关联记录列表(反向外键) */}
<ReferenceManyField reference="comments" target="post_id">
<DataTable>
<TextField source="body" />
<DateField source="created_at" />
</DataTable>
</ReferenceManyField>
{/* 显示多个关联记录(ID数组) */}
<ReferenceArrayField source="tag_ids" reference="tags">
<SingleFieldList>
<ChipField source="name" />
</SingleFieldList>
</ReferenceArrayField>{/* Select from another resource (FK) */}
<ReferenceInput source="company_id" reference="companies" />
{/* Multi-select from another resource (array of IDs) */}
<ReferenceArrayInput source="tag_ids" reference="tags" />{/* 从另一个资源中选择(外键) */}
<ReferenceInput source="company_id" reference="companies" />
{/* 从另一个资源中多选(ID数组) */}
<ReferenceArrayInput source="tag_ids" reference="tags" /><SimpleForm><TabbedForm>required()minLength(min)maxLength(max)minValue(min)maxValue(max)number()email()regex(pattern, message)<TextInput source="title" validate={[required(), minLength(3)]} />useWatch()<SimpleForm><TabbedForm>required()minLength(min)maxLength(max)minValue(min)maxValue(max)number()email()regex(pattern, message)<TextInput source="title" validate={[required(), minLength(3)]} />useWatch()// posts/index.ts
export default {
list: PostList,
create: PostCreate,
edit: PostEdit,
icon: PostIcon,
recordRepresentation: (record) => record.title, // How records appear in references
};// posts/index.ts
export default {
list: PostList,
create: PostCreate,
edit: PostEdit,
icon: PostIcon,
recordRepresentation: (record) => record.title, // 记录在引用中的显示方式
};const dataProvider = {
...baseDataProvider,
archivePost: async (id) => { /* custom logic */ },
};
// Call via useDataProvider and useQuery:
// const dp = useDataProvider();
// const { data } = useQuery(['archivePost', id], () => dp.archivePost(id));const dataProvider = {
...baseDataProvider,
archivePost: async (id) => { /* 自定义逻辑 */ },
};
// 通过useDataProvider和useQuery调用:
// const dp = useDataProvider();
// const { data } = useQuery(['archivePost', id], () => dp.archivePost(id));useStore()const [theme, setTheme] = useStore('theme', 'light');useStore()const [theme, setTheme] = useStore('theme', 'light');const notify = useNotify();
const redirect = useRedirect();
const refresh = useRefresh();
notify('Record saved', { type: 'success' });
redirect('list', 'posts'); // Navigate to /posts
redirect('edit', 'posts', 123); // Navigate to /posts/123
refresh(); // Invalidate all queriesconst notify = useNotify();
const redirect = useRedirect();
const refresh = useRefresh();
notify('Record saved', { type: 'success' });
redirect('list', 'posts'); // 导航到/posts
redirect('edit', 'posts', 123); // 导航到/posts/123
refresh(); // 使所有查询失效<CanAccess>useCanAccess<CanAccess>useCanAccess