A remote, third-party JSONP server provides my CanJS script with a list of results like this one:
[
{ "class": "ABaseClass", "value": "1"},
{ "class": "ASubClass", "value": "2"},
{ "class": "ABaseClass", "value": "3"},
{ "class": "ASubClass", "value": "4"},
...
]
where type is the intended object class, defined in CanJS using can.Model.extend:
The following simplified code demonstrates the CanJS setup:
ABaseClass = can.Model.extend({ ... }, {
'findAll': { 'url': 'the url', 'dataType': "jsonp" }
// this is modified source code and may not run
});
// ASubClass is a subclass of ABaseClass.
ASubClass = ABaseClass.extend({ ... }, { ... });
Problem:
When ABaseClass.findAll({}, function(data) { ... }) is called, which calls the JSONP endpoints for more objects, the callback obtains a list of CanJS models, but only of class ABaseClass.
Question:
Is there a helper method provided by CanJS to automatically create subclasses based on a field within a list of objects? If not, how can I go about implementing one?
Expected output:
[
(new ABaseClass(...)),
(new ASubClass(...)),
(new ABaseClass(...)),
(new ASubClass(...)),
...
]
Environment:
- CanJS: 1.17
- jQuery: 1.10.1
- I cannot control what types of objects the endpoint returns.
- Multiple AJAX calls is not an accepted solution.
The easiest way to do this would be to override the
modelsmethod and find the correct model for the class like this:What this does is:
findAllreturns it sends it's result to themodelsmethod.modelsmethod then loops over each of the results.window[result.class])modelon the constructor to construct/update the model instance.can.Listand return it.I have tested this in CanJS 2.0.x and it works fine here.
You can find more details about how this all works in the docs:
It looks like these will be Deprecated in CanJS 2.1.0 in favour of
.parseModelsand.parseModel