内部组件中的装饰器不会更新数据

时间:2016-02-01 19:47:58

标签: ractivejs

尽管有this stackoverflow question的建议,我仍然无法使用正确的数据更新装饰器。与引用的问题不同,现在装饰器位于组件内部。这是代码(参考:this jsfiddle):

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>

和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"}])

初始化之后和数据集更新后,单击带有装饰器提供的行为的链接仍会返回原始数据,而不是更新的数据。

这里有什么建议吗?提前感谢您提供的任何见解。

1 个答案:

答案 0 :(得分:2)

两件事:

1)如果你想让它更新,装饰器函数应该返回一个带有拆卸方法和可选的更新方法的对象 2)在update方法中,提供了新的参数,你需要使用它们来更新装饰器状态。

用你的例子,在我最好的咖啡因中,将会是(见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

对于此用例,不需要重新订阅click事件,但通常该模式对于需要重新运行拆卸和初始化逻辑的情况很有用:

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);
        }
    }


}