Ractivejs装饰器不一致地初始化

时间:2015-06-30 20:19:32

标签: ractivejs

参考:http://jsfiddle.net/ffmqd0zz/

HTML:

<div id='books_container'/>

<script type='ractive/template' id="books">
  {{#books}}
  <div decorator='decoration' id="{{id}}">
      <span> title: {{ title }}</span>
      <span> id: {{ id }}</span>
  </div>
  {{/books}}
</script>

的javascript:

var MyDecorator = function(node) {
    console.log("init MyDecorator for id: " + $(node).attr('id'));
    return { teardown: function() {}};
};

var books = new Ractive({
    el: '#books_container',
    template: '#books',
    data: {books: [{"id": 1174,"title": "franny and zoey"},
                   {"id": 1175,"title": "moby duck"}]},
    decorators: { decoration: MyDecorator }
  });

console.log("init complete")

books.set('books', [{"id": 1176,"title": "life, the universe and stuff"},
                    {"id": 1177,"title": "yellowbrick road"},
                    {"id": 1178,"title": "grapes of wrath"} ]);

注意装饰器初始化被记录到控制台。

初始化Ractive时,&#34;书籍中的两个初始项目&#34; list正确装饰,如console.log消息所示。但是,当使用&#34; books.set()&#34;更改列表时,Ractive仅装饰列表中的第三个项目,并且未初始化ID为1176和1177的书籍的装饰器。

似乎只是通过初始化第三个添加项目上的装饰器来优化性能,跳过前两个,即使它们已被替换。

我做错了,还是这个错误?有人可以建议一个解决方法。

提前致谢

2 个答案:

答案 0 :(得分:2)

Ractive只会更新变化的内容。使用节点列表({{each}}),有两种策略用于更新:

  1. 显式数组修改(如推送或拼接(或合并))会产生相同的DOM节点修改 - 这意味着如果不修改DOM节点,则保持完整,否则将被删除或插入。
  2. 设置数组会重用DOM节点,但即使在这种情况下,也只会使用每个列表项的结构更新已更改的内容。
  3. 因此对于装饰器,如果没有参数,Ractive将不会更新它们。每种方法都可以更改此选项以向装饰器添加参数:

    <div decorator='decoration:{{id}}' id="{{id}}">
    

    现在装饰器将被拆除并重新初始化,如果它依赖的数据发生变化(见http://jsfiddle.net/ffmqd0zz/2/)。

    某些文档尚未更新,您还可以向装饰器返回参数添加update方法,该参数将被调用以代替装饰器在参数值更改时被删除:

    var MyDecorator = function(node, title) {
        console.log('new decorator', title);
        function tooltip( title ) {
            node.title = title;
        }
    
        return { 
            teardown: function() {},
            update: function( title ) {
                tooltip(title);
            }
        };
      };
    

    请参阅http://jsfiddle.net/ffmqd0zz/3/

答案 1 :(得分:0)

作为一种解决方法,您可以一次弹出和推送一个数组元素。 See full example。相关代码:

books.pop('books');
books.pop('books');

books.push('books', {"id": 1176,"title": "life, the universe and stuff"});
books.push('books', {"id": 1177,"title": "yellowbrick road"});
books.push('books', {"id": 1178,"title": "grapes of wrath"});

我不确定您看到的行为是否是由于某个错误造成的。就像你说的那样,它可能是Ractive优化性能。来自Ractive docs的一个有说服力的消息:“指令只是Ractive的指令 - 它们实际上并没有作为属性添加到元素中。”