I wouldn't instantiate directly (my tests case was simply to show why
parseModel didn't work).
I would likely be instantiating via can.List.Map or can.Map.prototype.define instead.
Let me paint a picture of the backend API we're dealing with:
We have an endpoint that returns "products",
for which we have defined a model that implements findOne and
findAll. No problem there.
Example response:
- [
- {
- legacyItemNo: 123,
- displayName: 'Some Product',
- enteredQuantity: 0
- },
- {
- legacyItemNo: 456,
- displayName: 'Some Other Product',
- enteredQuantity: 0
- },
- {...},
- {...}
- ]
We have another endpoint that returns an "order
review", and in this response, one of the properties is an
array that closely resembles what we get back from the
"products" endpoint. We have also defined a model for
this, which implements a findOne method.
Example response:
- {
- totalPrice: 123.00,
- itemCount: 4,
- deliveryInfo: { ... },
- products: [
- {
- legacyItemNo: 456,
- displayName: 'Some Other Product',
- enteredQuantity: 0
- },
- {
- legacyItemNo: 456,
- displayName: 'Some Other Product',
- enteredQuantity: 0
- },
- {...},
- {...},
- {...}
- ]
- }
For both of these responses, we need to convert the
attribute names for the products themselves (as well as provide
other computed methods). So in a nutshell, we need to sometimes
treat sub properties of one model as if they are instances of
another model. The current solution for doing this is to use
can.Map.prototype.define to cast the "products"
attribute as an instance of a "product list".
- var OrderModel = can.Model.extend({
- findOne: function () {...}
- }, {
- define: {
- products: {
- Type: Product.List
- }
- }
- });