To create an array of Model’s, managed by an ArrayController (ArrayProxy). Requirements
Use ArrayController (ArrayProxy) abstraction to encapsulate the array of Model’s Convert objects input to ArrayProxy automagically upon insertion into the ArrayProxy Do not lazy convert at access time
App.AddressModel = Ember.Object.extend({
address_name: null,
address: null,
printme: function() {
console.log("Just making sure the array turned into an AddressModel");
},
});
App.addressArray = Ember.ArrayProxy.create({
transformFrom: function(item) {
},
transformTo: function(item) {
},
arrayContentWillChange: function(startIdx, removeAmt, addAmt) {
},
});
Someone in the IRC channel mentioned trying dynamic properties. This resulted in a, what appeared to be by logic and empirical evidence, a recursive result. No doubt from making content both the dynamically generated variable and the ‘trigger/exported’ variable.
Again, a seemingly recursive result. Upon receiving a arrayContentWillChange notification I generate an AddressModel from the given array index item(s). I then set the old indexed item to the created Model and an arrayContentWillChange event is triggered again, repeat … recurse.
https://github.com/emberjs/ember.js/pull/554#issuecomment-5401112 tomdale mentions in the above post to try using transformFrom and transformTo to cast the incoming and/or outgoing data. These function don’t seem to exist [http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.8.js].
https://github.com/emberjs/ember.js/pull/554 tomdale’s suggestion to the original solution/post to this problem seems to generalize better than the model implementation introduced by jedwood, however, in Backbone.js handles this problem by using the special model variable and I found it to work well.
How do I extend ArrayProxy to convert all incoming object, to be managed, into an AddressModel?
I took the approach mentioned by Tom Dale which overwrites the replace
method. It also registers an observer for the content
property to assure that the content is a typed version of the array, see http://jsfiddle.net/pangratz666/XCLmE/:
App.ModelArrayProxy = Ember.ArrayProxy.extend({
modelType: Ember.required,
_typedArray: function(objects) {
var modelType = this.get('modelType');
var array = objects.map(function(item) {
// check if item is an instance of type
if (!(item instanceof modelType)) {
// create a new instance of type and pass the hash
return modelType.create(item);
}
// just return the item, since it's already of type modelType
return item;
});
return array;
},
contentChanged: function() {
if (!this.get('setTypedContent')) {
var content = this.get('content');
this.set('setTypedContent', true);
this.set('content', this._typedArray(content));
this.set('setTypedContent', false);
}
}.observes('content'),
replace: function(idx, amt, objects) {
this._super(idx, amt, this._typedArray(objects));
}
});
This ModelArrayProxy can then be used as a "normal" ArrayProxy
:
// model declaration
App.AddressModel = Ember.Object.extend({
...
});
// create a proxy for given modelType
App.proxy = App.ModelArrayProxy.create({
content: [],
modelType: App.AddressModel
});
var myArray = [{
address_name: 'address_name 1',
address: 'address 1'},
{
address_name: 'address_name 2',
address: 'address 2'}];
// set content with "normal" objects
App.proxy.set('content', myArray);
// invoke 'log' on all items in array
App.proxy.forEach(function(item) {
item.log();
});
// push a normal object
App.proxy.pushObject({
address_name: 'address_name 3',
address: 'address 3'
});
// push an instance of App.AddressModel
App.proxy.pushObject(App.AddressModel.create({
address_name: 'address_name 4',
address: 'address 4'
}));
// invoke 'log' on all items in array
App.proxy.forEach(function(item) {
item.log();
});
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