Reputation: 338
I'm confused. I have following model, transforms for attr tags and fixtures:
Tracker.Story = DS.Model.extend({
title: DS.attr('string'),
tags: DS.attr('array', []),
});
DS.ArrayTransform = DS.Transform.extend({
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized.split(',');
}
});
Tracker.register("transform:array", DS.ArrayTransform);
Tracker.Story.FIXTURES = [
{
id: 1,
title: "Some story",
tags: ["tag1", "tag2", "tag3"],
}
and template
{{#each itemController="story"}}
{{title}}
{{#each tag in tags}}
{{tag}}
{{/each}}
{{/each}}
It's works nice for story from FIXTURES. I added new story via interface, where input field define as:
{{input type="text" value=tags}}
Transforms correctly works and return array from string ([1,2,3] from "1,2,3" for example).
But failed rendering tags for added story with next messages:
Assertion failed: The value that #each loops over must be an Array. You passed 1 ember.js:417
Uncaught TypeError: Object 1 has no method 'addArrayObserver' ember.js:22976
Uncaught Error: Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.
Upvotes: 0
Views: 436
Reputation: 47367
The input helper doesn't support saving items as an array. The reason it's showing up in the input field correctly is because toString is being called on the object and toString of an array is 1,2,3 etc... As you change the input field it's blasting away the underlying array and saving it as a string 1,2,3.
The transform is only executed while loading/saving the model, not on every get/set to the underlying model.
You're best bet would be to associate the input field with a different property and as that field changes you update the underlying field with an array.
Something like this would work:
http://emberjs.jsbin.com/EMapanu/3/edit
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['red', 'yellow', 'blue'];
},
setupController: function(controller, model){
this._super(controller, model);
controller.set('fakeModel', model);
}
});
App.IndexController = Em.ArrayController.extend({
modelUpdater: function(){
var fm = this.get('fakeModel');
if(!(fm instanceof Array)){
fm = (this.get('fakeModel') || "").split(',');
}
this.set('model', fm);
}.observes('fakeModel')
});
Upvotes: 2