【问题标题】:Ractivejs decorator inconsistently initializedRactivejs 装饰器初始化不一致
【发布时间】:2015-06-30 20:19:32
【问题描述】:

参考: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 初始化时,“books”列表中的两个初始项目被正确修饰,如 console.log 消息所示。但是,当使用“books.set()”更改列表时,Ractive 只会装饰列表中的第三项,并且不会初始化 id 为 1176 和 1177 的书籍的装饰器。

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

是我做错了,还是这是一个错误?请有人提出解决方法。

提前致谢

【问题讨论】:

    标签: ractivejs


    【解决方案1】:

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

    1. 诸如推送或拼接(或合并)之类的显式数组修改会产生相同的 DOM 节点修改 - 这意味着 DOM 节点在未修改时保持不变,否则将被删除或插入。
    2. 设置数组会重用 DOM 节点,但即使在这种情况下,也只会使用每个列表项的结构更新已更改的内容。

    所以对于装饰器,如果它们没有参数,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/

    【讨论】:

    • 谢谢,马蒂。你的两个例子都没有像我预期的那样工作。但他们给了我很棒的新见解,我能够从中找到我需要的地方。
    【解决方案2】:

    作为一种解决方法,您可以一次弹出和推送数组元素。 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 的指令——它们实际上并没有作为属性添加到元素中。”

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 1970-01-01
      • 2013-03-17
      • 2019-01-24
      • 2016-01-07
      • 2018-05-04
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      相关资源
      最近更新 更多