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
models
method and find the correct model for the class like this:What this does is:
findAll
returns it sends it's result to themodels
method.models
method then loops over each of the results.window[result.class]
)model
on the constructor to construct/update the model instance.can.List
and 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
.parseModels
and.parseModel