ref: http://jsfiddle.net/xwLk2vb0/
Person = Ractive.extend({
template: "<p>the person named {{name}}</p>",
computed: {
name: {
get: function(){
if(typeof(this.get('_name'))=='undefined'){return "nameless"}
else{return this.get('_name')}
},
set: function(val){
this.set('_name',val)
}
}
}
});
people_model = new Ractive({
el: '#people_container',
template: '{{#people}}<person/>{{/}}',
data: {
people: [{},{},{}]
},
components :{person : Person}
});
people_model.set('people.0.name','Spongebob')
I can't understand why the last line doesn't invoke the setter on the 'name' computed attribute and then update the rendered templates. Can someone offer any insight, please.
thanks in advance
The short answer is that computed properties are 'owned' by the component on which they live; you can't interact with them via their parent. I wrote a bit about why that's the case here - it doesn't exactly describe your situation, but the fact is that there's no mapping between the
Personcomponent'sname, and thenameproperty of the object it relates to.nameis effectively shadowed.This is a Good Thing insofar as it makes code easier to follow and reason about - if an object were populated with additional values just because they coincided with computed properties on a component (i.e, each object in the
peoplearray would suddenly get aname: 'nameless'property), you could easily end up in a brain-bending situation trying to figure out where some data came from in your app.So the solution is to have a 'proxy' computed property that acts as an accessor for the real
nameproperty, like so: http://jsfiddle.net/muoz44ec/. Note that we're explicitly linkingnameinside the component tothis.nameon the person object.