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
Person
component'sname
, and thename
property of the object it relates to.name
is 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
people
array 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
name
property, like so: http://jsfiddle.net/muoz44ec/. Note that we're explicitly linkingname
inside the component tothis.name
on the person object.