我有一个使用自定义绑定的SyncFusion网格,我遇到了两个问题。
1.当最初请求数据填充网格时,它没有显示加载微调器,即使我已经通过一个副作用和一个Redux状态属性(isLoading)设置了加载微调器。通过控制台日志,我可以看到副作用按预期运行,但没有显示微调器。
1.一旦初始数据请求返回并填充网格,微调器就会出现,并且不会停止。我相信这与正在添加的行详细信息模板有关。如果我删除详细信息模板,微调器就不会出现。我已经在外部columnChooser按钮中添加了hideSpnner,单击此按钮后,一切都正常工作。
它不是在我想它出现的时候出现,然后出现而不消失。
一旦我通过了这个初始数据请求并通过外部列选择器按钮强制hideSpinner(),后续数据请求在分页和排序时就可以正常工作,微调器会相应地显示。
不确定这里是否有SyncFusion用户社区,但希望有人能提供帮助。
下面是我的部分:
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { DataStateChangeEventArgs } from "@syncfusion/ej2-react-grids";
import { ServiceRequest } from "./models/ServiceRequest.interface";
import { ServiceRequestResult } from "./models/ServiceRequestResult.interface";
import csmService from "./services/csmMyRequestService";
interface AsyncState {
isLoading: boolean;
isSuccess: boolean;
isError: boolean;
}
interface MyRequestState extends AsyncState {
result: ServiceRequest[];
count: number;
}
const initialState: MyRequestState = {
isLoading: false,
isSuccess: false,
isError: false,
result:[],
count: 0
}
export const getMyRequests = createAsyncThunk(
'csm/getMyRequests',
async (gridCriteria: DataStateChangeEventArgs) => {
try {
return await csmService.getMyRequests(gridCriteria);
} catch (error) {
console.log('Error: ', error);
}
});
export const csmMyRequestSlice = createSlice({
name: 'csmMyRequest',
initialState,
reducers: {},
extraReducers(builder) {
builder
.addCase(getMyRequests.pending, (state) => {
state.isLoading = true;
})
.addCase(getMyRequests.fulfilled, (state, action) => {
state.result = action.payload?.myRequests || [];
state.count = action.payload?.count || 0;
state.isLoading = false;
state.isSuccess = true;
})
.addCase(getMyRequests.rejected, (state) => {
state.result = [];
state.count = 0;
state.isLoading = false;
state.isError = true;
})
},
});
export default csmMyRequestSlice.reducer;
下面是我的组件:
import { FC, useEffect, useRef, useState } from 'react';
import { Internationalization } from '@syncfusion/ej2-base';
import { ColumnDirective, ColumnsDirective, DataStateChangeEventArgs, Grid, GridComponent } from '@syncfusion/ej2-react-grids';
import { Inject, Page, Sort, Filter, FilterSettingsModel, Resize, ColumnChooser, DetailRow } from '@syncfusion/ej2-react-grids';
import { useAppDispatch, useAppSelector } from '../../../hooks/redux/hooks';
import styles from './MyRequests.component.module.scss';
import { getMyRequests } from '../csmMyRequestSlice';
import { IconButton, styled, Tooltip, tooltipClasses, TooltipProps } from '@mui/material';
import ViewColumnIcon from '@mui/icons-material/ViewColumn';
import { ServiceRequestResult } from '../models/ServiceRequestResult.interface';
let instance = new Internationalization();
const MyRequestsComponent: FC = () => {
const dispatch = useAppDispatch();
const { isLoading, result, count, isSuccess } = useAppSelector((state) => state.csmMyRequestReducer);
let initialMyRequests = { result: [], count: 0 };
const [myRequests, setMyRequests] = useState<ServiceRequestResult>(initialMyRequests);
const pageSettings = {
pageSize: 10,
pageSizes: ["10", "20", "30", "40", "50"]
};
const sortSettings = {
columns: []
};
const columnChooserSettings = {
hideColumns: [
"Contact",
"Request Subtype",
"Reference",
"Sys. Logged Date",
"Sys. Closed Date"
]
};
let myGridInstanceRef: Grid | null;
const format = (value: Date) => {
return instance.formatDate(value, { skeleton: 'yMd', type: 'date' });
};
const dataBound = () => {
}
const dataStateChange = (gridCriteria: DataStateChangeEventArgs) => {
if (myGridInstanceRef && gridCriteria.action) {
const requestType = gridCriteria.action.requestType;
switch (requestType) {
case 'paging':
case 'sorting':
dispatch(getMyRequests(gridCriteria));
break;
}
}
};
const CustomWidthTooltip = styled(({ className, ...props }: TooltipProps) => (
<Tooltip {...props} classes={{ popper: className }} />
))({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 500,
fontSize: 13,
color: 'white',
},
});
function gridDetailTemplate(props: any) {
return (
<CustomWidthTooltip title={props.Detail}><p className={`${styles['RequestDetailText']}`}>Detail: {' '}{props.Detail}</p></CustomWidthTooltip>
);
}
let template: any = gridDetailTemplate;
const columnChooserClick = (event: React.MouseEvent<HTMLElement>) => {
if (myGridInstanceRef) {
myGridInstanceRef.hideSpinner(); //Forced hide of spinner here
myGridInstanceRef.columnChooserModule.openColumnChooser();
}
};
useEffect(() => {
if (myGridInstanceRef) {
if (isLoading) {
console.log('is Loading show spinner'); //Goes through here but spinner doesn't display
myGridInstanceRef.showSpinner();
} else {
console.log('not Loading hide spinner'); //Who knows if it gets hidden as it never gets displayed
myGridInstanceRef.hideSpinner();
}
}
}, [isLoading])
useEffect(() => {
if (myGridInstanceRef && isSuccess) {
setMyRequests({ result: result, count: count });
}
}, [result, isSuccess])
useEffect(() => {
if (myGridInstanceRef) {
columnChooserSettings.hideColumns.forEach((field) => {
myGridInstanceRef!.hideColumns(field);
});
const gridCriteria = { skip: 0, take: 10 };
dispatch(getMyRequests(gridCriteria));
}
}, [])
return (
<div className={`${styles['RequestSection']}`}>
<legend className={`${styles['RequestLegend']}`}>My Requests:
<Tooltip title="Show/Hide Columns">
<IconButton
className={`${styles['ColumnChooser']}`}
onClick={columnChooserClick}
size="small"
>
<ViewColumnIcon />
</IconButton>
</Tooltip>
</legend>
<div className={`${styles['RequestGridContainer']}`}>
<GridComponent
ref={(g) => (myGridInstanceRef = g)}
dataSource={myRequests}
allowPaging={true} pageSettings={pageSettings}
allowSorting={true} allowMultiSorting={true} sortSettings={sortSettings}
allowResizing={true}
allowReordering={true}
showColumnChooser={true}
detailTemplate={template.bind(this)}
dataBound={dataBound.bind(this)}
dataStateChange={dataStateChange.bind(this)}
height='100%'
>
<ColumnsDirective>
<ColumnDirective field='ServiceRequestTag' headerText='Request #' />
<ColumnDirective field='Caller.Name' headerText='Caller' />
<ColumnDirective field='Source' />
<ColumnDirective field='Contact.ContactName' headerText='Contact' />
<ColumnDirective field='ServiceType.ServiceTypeName' headerText='Service Type' />
<ColumnDirective field='ServiceRequestType.ServiceRequestTypeName' headerText='Request Type' />
<ColumnDirective field='ServiceRequestSubtype.ServiceRequestSubtypeName' headerText='Request Subtype' />
<ColumnDirective field='Poi.Address' headerText='POI Address' />
<ColumnDirective field='Poi.CityTown' headerText='POI City/Town' />
<ColumnDirective field='ReferenceNumbers' headerText='Reference' />
<ColumnDirective field='OwnerName' headerText='Owner' />
<ColumnDirective field='Status.StatusName' headerText='Status' width='100' />
<ColumnDirective field='LoggedByName' headerText='Logged By' />
<ColumnDirective field='LoggedDate' headerText='Logged Date' type='datetime' format='dd MMM yyyy HH:mm' />
<ColumnDirective field='SystemLoggedDate' headerText='Sys. Logged Date' type='datetime' format='dd MMM yyyy HH:mm' />
<ColumnDirective field='ClosedByName' headerText='Closed By' />
<ColumnDirective field='ClosedDate' headerText='Closed Date' type='datetime' format='dd MMM yyyy HH:mm' />
<ColumnDirective field='SystemClosedDate' headerText='Sys. Closed Date' type='datetime' format='dd MMM yyyy HH:mm' />
<ColumnDirective field='DueDate' headerText='Due Date' type='datetime' format='dd MMM yyyy HH:mm' />
</ColumnsDirective>
<Inject services={[Page, Sort, Resize, ColumnChooser, DetailRow]} />
</GridComponent>
</div>
</div>
)
}
export default MyRequestsComponent;
1条答案
按热度按时间kb5ga3dv1#
我认为问题出在
myGridInstanceRef
变量上。它不是React ref意义上的 true 引用。它在每个渲染周期都被重新声明,所以很可能有同步问题。这可能应该声明为React引用,以便在不同的渲染周期中保持稳定的引用。
示例: