Going through Ember.js documentation, I am not able to figure out how to create nested models. Assume that I have the following JSON:
App.jsonObject = {
id: 1812,
name: 'Brokerage Account',
positions: [
{
symbol: 'AAPL',
quantity: '300'
},
{
symbol: 'GOOG',
quantity: '500'
}
]
}
If I create a model object like this
App.account = Ember.Object.create(App.jsonObject);
only the top level properties (id and name) get bound to templates, the nested positions array does not get bound correctly. As a result adding, deleting or updating positions does not affect the display. Is there a manual or automatic way to transform the positions array so that it is binding aware (similar to an ObservableCollection in WPF)?
I have created a jsfiddle to experiment with this: http://jsfiddle.net/nareshbhatia/357sg/. As you can see, changes to top level properties are reflected in the output, but any change to the positions is not. I would greatly appreciate any hints on how to do this.
Thanks.
Naresh
Edit: The ideal situation would be if Ember.js could somehow parse my JSON feed into nested Ember.js objects. For example, what if I explicitly define my classes as follows, could that assist Ember.js to create the right objects?
App.Account = Ember.Object.extend({
id: null,
name: null,
positions: Ember.ArrayProxy.create()
});
App.Position = Ember.Object.extend({
symbol: null,
quantity: null,
lastTrade: null
});
App.account = App.Account.create(App.jsonObject);
My eventual goal is to display this structure in a hierarchical grid which can expand/collapse at the account level. Coming from the WPF/Silverlight world, it is fairly easy to do something like this. All you need to do is to specify a nested template for the grid in XAML and it knows how to interpret your model. You can find an example here - it is not too difficult to follow. I am wondering if something like this is possible in Ember.js.
You need to use pushObject
not push
when adding to Ember array objects with bindings. And you should probably use get()
when accessing the positions
property. See my jsFiddle for the corrections.
http://jsfiddle.net/ud3323/Y5nG5/
I've created a recursive object factory that you may like:
It will iterate over the object and create Ember Arrays or nested objects, returning a full Ember Object tree!
Here is the source for your reference, and a JS fiddle: http://jsfiddle.net/SEGwy/2/
Please note: the fiddle writes the output to the console, so you won't see any output on the screen.
RecursiveObject = {
// http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
TypeOf: function (input) {
try {
return Object.prototype.toString.call(input).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
} catch (e) {
return typeof input;
}
},
// Factory method..
create: function (args) {
args = args || {};
ctxt = this;
switch (this.TypeOf(args)) {
// Return an Ember Array
case "array":
var result = Ember.A();
for (var i = 0; i < args.length; i++) {
x = this.create(args[i]);
result.push(x);
};
break;
// Or a recursive object.
case "object":
var result = Ember.Object.create();
$.each(args, function (key, value) {
result.set(key, ctxt.create(value));
});
break;
default:
// Or just return the args.
result = args;
break;
}
return result;
}
}
// Example
jsonObject = {
id: 1812,
name: 'Brokerage Account',
positions: [
{
symbol: 'AAPL',
quantity: '300'
},
{
symbol: 'GOOG',
quantity: '500'
}
]
}
x = RecursiveObject.create(jsonObject);
console.log(x);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With