Hi bryntum Team!
im working with React + Redux.
im having the following flow:
*loading data from server=>
*passing it to scheduler via props=>
*data is displayed well=>
*on changing/deleting events im calling an jsx action, calling server for validation for instanse=>
*getting the updated data from the server and updating the state on the reducer(let say different events times) =>
*Render method of the scheduler component is called **with the new data on the props**
*display of the old events stays.
should i call a refresh method or somthing?
thank you!
Support Forum
sure.. one important thing, i have noticed it happens when im draging an event and then
retriving the new data.
meaning, calling the api without changing events by the ui does work, playing on the ui and then calling the api doesnt
scheduler component:
export default class Scheduler extends pComponent {
constructor(props) {
super(props);
this.state = {
features: {
dependencies: true,
dependencyEdit: false,
eventDragCreate: false,
eventDrag: true,
eventResize: false,
headerZoom: true,
contextMenu: {
processCellItems: () => false,
},
scheduleContextMenu: {
items: {
addEvent: false,
}
},
};
}
render() {
return (<div>
<BryntumScheduler
ref={'scheduler'}
events={this.props.data.events}
resources={this.props.data.resources}
features={this.state.features}
dependencies={this.props.data.dependencies}
columns={[
{text: '', field: 'name', width: 160, disabled: true}
]}
startDate={new Date(2020, 2, 1)}
endDate={new Date(2020, 2, 7)}
/>
</div>
)
}
};
actions: hard coded updating an event and dispatch the changes
api.updateData= function(dispatch, getState) {
return function() {
return schedulerService.fetchSchdulerData()
.then((response) => {
response.data.events[0].startDate = new Date(2020, 2, 4, 10)
response.data.events[0].endDate = new Date(2020, 2, 4, 11)
dispatch(actions.fetchSchedulerDataFinished(data));
});
}
};
return the updated state. which cause re-render with the updated data.
reducer:
export default function(state = Map(defaultState), action) {
switch(action.type){
case schedulerActionTypes.FETCH_DATA_FINISHED:
state = state.set('schedulerData', action.payload);
return state;
default:
return state;
}
}
retriving the new data.
meaning, calling the api without changing events by the ui does work, playing on the ui and then calling the api doesnt
scheduler component:
export default class Scheduler extends pComponent {
constructor(props) {
super(props);
this.state = {
features: {
dependencies: true,
dependencyEdit: false,
eventDragCreate: false,
eventDrag: true,
eventResize: false,
headerZoom: true,
contextMenu: {
processCellItems: () => false,
},
scheduleContextMenu: {
items: {
addEvent: false,
}
},
};
}
render() {
return (<div>
<BryntumScheduler
ref={'scheduler'}
events={this.props.data.events}
resources={this.props.data.resources}
features={this.state.features}
dependencies={this.props.data.dependencies}
columns={[
{text: '', field: 'name', width: 160, disabled: true}
]}
startDate={new Date(2020, 2, 1)}
endDate={new Date(2020, 2, 7)}
/>
</div>
)
}
};
actions: hard coded updating an event and dispatch the changes
api.updateData= function(dispatch, getState) {
return function() {
return schedulerService.fetchSchdulerData()
.then((response) => {
response.data.events[0].startDate = new Date(2020, 2, 4, 10)
response.data.events[0].endDate = new Date(2020, 2, 4, 11)
dispatch(actions.fetchSchedulerDataFinished(data));
});
}
};
return the updated state. which cause re-render with the updated data.
reducer:
export default function(state = Map(defaultState), action) {
switch(action.type){
case schedulerActionTypes.FETCH_DATA_FINISHED:
state = state.set('schedulerData', action.payload);
return state;
default:
return state;
}
}
oh, sorry about that.
any suggestions what may render the the data correctly?
scheduler component:
actions: hard coded updating an event and dispatch the changes
return the updated state. which cause re-render with the updated data.
reducer:
any suggestions what may render the the data correctly?
scheduler component:
export default class Scheduler extends pComponent {
constructor(props) {
super(props);
this.state = {
features: {
dependencies: true,
dependencyEdit: false,
eventDragCreate: false,
eventDrag: true,
eventResize: false,
headerZoom: true,
contextMenu: {
processCellItems: () => false,
},
scheduleContextMenu: {
items: {
addEvent: false,
}
},
};
}
render() {
return (<div>
<BryntumScheduler
ref={'scheduler'}
events={this.props.data.events}
resources={this.props.data.resources}
features={this.state.features}
dependencies={this.props.data.dependencies}
columns={[
{text: '', field: 'name', width: 160, disabled: true}
]}
startDate={new Date(2020, 2, 1)}
endDate={new Date(2020, 2, 7)}
/>
</div>
)
}
};
api.updateData= function(dispatch, getState) {
return function() {
return schedulerService.fetchSchdulerData()
.then((response) => {
response.data.events[0].startDate = new Date(2020, 2, 4, 10)
response.data.events[0].endDate = new Date(2020, 2, 4, 11)
dispatch(actions.fetchSchedulerDataFinished(data));
});
}
};
reducer:
export default function(state = Map(defaultState), action) {
switch(action.type){
case schedulerActionTypes.FETCH_DATA_FINISHED:
state = state.set('schedulerData', action.payload);
return state;
default:
return state;
}
}
From the code you have posted, it is not clear to me how the updated data finds its way to the Scheduler.
Note: changing the items inside of the events (resources, dependencies) is not enough for the change to be sensed by React. It is necessary to change the object itself. Therefore we have updateState method in our demo:
- Scheduler property events (resources and dependencies too) are bound to the respective keys in data object of props.
<BryntumScheduler ref={'scheduler'} events={this.props.data.events} resources={this.props.data.resources} dependencies={this.props.data.dependencies} />
- reducer sets 'schedulerData' of state
state = state.set('schedulerData', action.payload);
Note: changing the items inside of the events (resources, dependencies) is not enough for the change to be sensed by React. It is necessary to change the object itself. Therefore we have updateState method in our demo:
const updateState = function(state, item) {
return { ...state, ...item };
}; // eo function updateState
hi Saki,
your right. there is another wrapper which pass the 'data' on the props.:
the container gets the 'schedulerData' pass it as sData to the wrapper.
container:
wrapper:
regarding the note you have mentioned, i have also tried to do deepCopy to the events on the actions and sent it to the component.
i would like to check the updateState you have mentioned. can you send me a link for that demo please?
your right. there is another wrapper which pass the 'data' on the props.:
the container gets the 'schedulerData' pass it as sData to the wrapper.
container:
let SchedulerPageContainer = connect(
(state) => {
return {
sData: state.get('schedulerData'),
};
},
mapDispatchToProps
)(SchedulerPage);
render() {
return (
<div className="scheduler-page">
<Scheduler getScheduler={this.getScheduler} data={this.props.sData.get('schedulerData')} onEventChange= {this.props.actions.schedulerGanttActions.OnEventChange}></Scheduler>
</div>
);
i would like to check the updateState you have mentioned. can you send me a link for that demo please?
It's React advanced demo in examples/react/javascript/advanced/ and the file itself is in src/redux/reducers/reducer.js.
Generally, the only thing needed would be to assign new events (resources, dependencies) to the Scheduler props and it should work without the necessity of calling any refresh or another UI related method.
You may also want to set syncDataOnLoad = true, however, this option only optimizes the data update so that the less DOM updates are necessary.
If everything else fails, post please a runnable showcase, we'll take a look.
Generally, the only thing needed would be to assign new events (resources, dependencies) to the Scheduler props and it should work without the necessity of calling any refresh or another UI related method.
You may also want to set syncDataOnLoad = true, however, this option only optimizes the data update so that the less DOM updates are necessary.
If everything else fails, post please a runnable showcase, we'll take a look.
they are all returns from the server on the actions, im just updating the first event to see if its behave as expected.Generally, the only thing needed would be to assign new events (resources, dependencies)
also, as iv mentioned, it does work at the first time, meaning - after a second change, such as dragging the first event, and calling the same api,
which modify the first event and return it back to the component, i expected the dragged event to return to the hard coded value, instead it stays on the place it was dragged to.
(i hope its clear)
ill take alook at the demo.
thank you
Well, generally it works. Navigate to https://bryntum.com/examples/scheduler/react/javascript/simple/build/index.html and then type in the browser console:
You can vary the various fields above and repeat the assignment. As you can see the event is always updated.
bryntum.query(i => i.$name === 'Scheduler').events = [{resourceId:'a',name:'New Meeting 1',startDate:'2017-02-07 11:00',endDate:'2017-02-07 14:00'}]