Our pure JavaScript Scheduler component


Post by xsys »

Hi guys,

I have a event model where a particular field's datatype is an object.
I have defined it as such in the class for it

{ name: 'additionalOptions', dataSource: 'additional_options' }

Mutating a value within the object doesn't register as a 'change' to the model. event.isModified remains as false and obviously this change is omitted for a sync request.

To illustrate, lets say I had a model like the below:

{
	name: 'Hey',
	startDate: DateObj,
	duration: 4,
	additionalOptions: {
		nestedValue: true,
		anotherNestedValue: false,
	}
}

If I mutate event.additionalOptions.nestedValue = false it doesn't registers this as the model's data has changed.
How can I achieve an outcome where this change DOES register as a model is modified.

I have considered serialising the object (additionalOptions) which would register a change but I realistically need to support my model having a field as an object.

Thanks


Post by johan.isaksson »

Hi,

There is no built in support for detecting changes in a nested object. We could perhaps introduce a new type of data field that would utilize Proxy to track changes of an object. But that would require you to access the object using our record, making changes on the original raw object would not be detected.

// Could work if we add a proxy field
store.first.additionalOptions.nestedValue = false;

// Would still not work
const additionalOptions = { nestedValue : true };
store.first.additionalOptions = additionalOptions;
additionalOptions.nestedValue = false;

If that would cover your usecase I could open a feature request for it?

Meanwhile, as an alternative to serializing you could try cloning it shallowly on changes. Something like:

store.first.additionalOptions.nestedValue = false;
store.first.additionalOptions = { ...store.first.additionalOptions };
Best regards,
Johan Isaksson

Post by Animal »

Changes to individual fields trigger the change event.

And individual fields can have a complex mapped dataSource. So you can use new fields:

{
	name       : 'nestedValue',
	dataSource : 'additional_options.nestedValue
},
{
	name       : 'otherNestedValue',
	dataSource : 'additional_options.otherNestedValue
}

Then this will trigger the store change event:

// Set the field which has a complex dataSource
store.first.nestedValue = true;

Post by xsys »

Thanks for the responses. I did manage to get around this by setting the whole again with the mutated value.

I didn't realise you could basically flatten complex data into fields, also a valid approach. This approach wont work if you need to store dynamic data in an object though. Is this documented ?

In this case, I am happy doing a shallow copy to trigger a change. Introducing a new supported data type of 'Object' could be useful and perhaps more performant to avoid cloning a whole object. Could be a 'nice to have' feature.

I can see immediate benefit of this use case being mentioned briefly in the docs though.


Post by johan.isaksson »

There is certainly room for improvement in docs on this topic, I'll add info on nested fields and how to update the value when using type : 'object'.

Regarding performance, shallowly cloning should be pretty cheap. Wrapping the nested object in a Proxy would make for a nicer user experience but dont think it would be more performant.

https://github.com/bryntum/support/issues/3458

Best regards,
Johan Isaksson

Post Reply