Notwithstanding the advice in this stackoverflow question, I'm still having trouble with decorators being updated with the correct data. Unlike the cited question, now the decorator is inside a component. Here's the code (ref: this jsfiddle):
the html:
<div id="container" />
<script type='template/racive' id='member_template'>
<p id='name_{{name}}' decorator='sayname:{{name}},{{id}}'>
{{id}}:{{name}}
<a href='#'>say my name</a>
</p>
</script>
and the coffeescript:
Sayname = (node,name)->
console.log "new decorator: #{name}"
$(node).find('a').on 'click',->
alert "I'm saying: #{name}"
teardown : ->
console.log "teardown #{name}"
$(node).off('click')
update : ->
console.log "update #{$(node).attr('id')} to #{name}"
Ractive.decorators.sayname = Sayname
Member = Ractive.extend
template: "#member_template"
window.family = new Ractive
el : '#container'
template: "{{#members}}<member name='{{name}}' id='{{id}}' />{{/members}}"
data:
members: [{id:1, name:"Barney"},
{id:2, name:"Fred"},
{id:3, name:"Wilma"},
{id:4, name:"Pebbles"}]
components:
member: Member
console.log "init complete"
family.set('members',[{id:5,name:"Sneezy"},{id:6,name:"Sleepy"},{id:7,name:"Happy"},{id:8,name:"Grumpy"}])
After initialization and after the dataset is updated, clicking the link with decorator-supplied behaviour still returns the original data, not the updated data.
Any suggestions what is wrong here? Thanks in advance for any insight offered.
Two things:
1) The decorator function should return an object with both a teardown method and optionally an update method if you want it to be updatable 2) In the update method, the new params are supplied you need to use them to update the decorator state.
With your example, in my best coffeescript, in would be (see https://jsfiddle.net/964qvry9/1/):
Sayname = (node,name)->
console.log "new decorator: #{name}"
$(node).find('a').on 'click',->
alert "I'm saying: #{name}"
decorator =
teardown : ->
console.log "teardown #{name}"
$(node).off('click')
update : (newName) ->
console.log "update #{$(node).attr('id')} to #{name}"
name = newName
For this use case, there's no need to resubscribe to the click event, but often the pattern is helpful for cases where you need to re-run the teardown and init logic:
function myDecorator( node, param ){
function init(param) {
//do setup work
}
function teardown() {
//do teardown work
}
init(param);
return {
teardown() { teardown(); },
update(param) {
teardown();
init(param);
}
}
}