Our resource store contains two different types of resources that are represented by different subclasses of ResourceModel. e.g. TypeAResourceModel and TypeBResourceModel. The incoming data has a discriminator defining which type of model should be created. Is there a specific field this can be mapped to so that the correct type of model is constructed?
We are familiar with the modelClass field for a store, however that only allows us to specify a single model class.
This would be similar to how the column store provides a 'type' specification allowing configuration of different column types that utilize different Column classes derived from Model
Store cannot contain records with different model classes. By design, a store contains a set of records with the one data model class, same as database table.
If you want to have "typeA" and "typeB" records, you can add a new field "type" to your data model and specify the type in there. After that check that flag in your code and fill-in fields that required for this type.
Both types would use the TerminalResourceModel class. We can get around this by wrapping our children in new TerminalResourceModel, however it would be nice if we didn't have to do this extra step.
How can I reproduce this? Tests pass just fine here:
t.iit('Initialize with tree data', t => {
const store = new MixedStore({
tree : true,
data : [
{
type : 'a',
name : 'Terminal',
children : [
{ type : 'b', name : 'Gate A' }
]
}
]
});
t.isInstanceOf(store.rootNode.firstChild, ModelA);
t.isInstanceOf(store.rootNode.firstChild.firstChild, ModelB);
});
Waiting for your testcase. meanwhile I tested with your code and it still passed
t.iit('Initialize with tree data', t => {
const store = new MixedStore({
tree : true,
data : [
{
id : 1,
type : 'a',
name : 'Terminal',
children : [
{ id : 2, type : 'b', name : 'Gate A' }
]
}
]
});
store.first.appendChild({id : 3, type : 'a', children : [ { id : 4, type : 'b'} ] })
t.isInstanceOf(store.rootNode.firstChild, ModelA);
t.isInstanceOf(store.rootNode.firstChild.firstChild, ModelB);
t.isInstanceOf(store.getById(3), ModelA);
t.isInstanceOf(store.getById(4), ModelB);
});
Here's the code I was able to use to reproduce. I see that we should be passing in a reference to 'this' in the model constructor, however the exported typescript model's constructor only accepts a single argument for data. Is there a way to inform the model which store it belongs to during construction in typescript?
Thanks, Jon
Tree demo
Code editor
Download code
app.module.js
Auto apply
import { SchedulerPro, ResourceModel, StringHelper } from '../../build/schedulerpro.module.js';
import shared from '../_shared/shared.module.js';
class Gate extends ResourceModel {
get doWork() { return 'gate model'; }
}
class Terminal extends ResourceModel {
get doWork() { return 'terminal model'; }
}
new SchedulerPro({
appendTo : 'container',
eventColor : null,
eventStyle : null,
resourceStore: {
modelClass: Gate,
createRecord(data, skipExpose = false, rawData = false) {
let modelClass = this.modelClass;
if (data.type === 'terminal') {
modelClass = Terminal;
}
// Works
//return new modelClass(data, this);
// Does not Work
return new modelClass(data);
}
},
features : {
tree : true,
},
rowHeight : 45,
barMargin : 5,
columns : [
{
type : 'tree',
text : 'Name',
width : 220,
field : 'name'
}, {
text : 'Model Type',
width : 90,
field : 'doWork'
}
],
viewPreset : 'hourAndDay',
resources: [{
name: 'Terminal A',
type: 'terminal',
children: [{
name: 'Gate A1',
type: 'gate'
}]
}]
});
Idle