2

我的团队目前正在使用 Ractive 来显示一系列警报。每个警报:

  • 使用 Ractive 渲染视图
  • 启动 Twitter widgets.js,它会做一些 DOM 操作(嵌入推文)
  • 稍后更改该视图中的数据(当用户选择不同的警报时)

由于 Twitter 的 DOM 更改会干扰 Ractive 的虚拟 DOM,我们目前使用在 Twitter完成ractive.reset()后重置 DOM - 这可以防止由于 Twitter 在 Ractive 背后操纵 DOM 而发生的一大堆 DOM 问题。widgets.jsreset()cannot appendChild of null

但是,在我们运行ractive.reset()表达式之后似乎不再起作用。

这是处理可能操纵 DOM 的其他库的正确方法吗?如何使表达式在 之后继续工作reset()

这是一个快速演示 - 请注意表达式在之前reset()但之后无效:

    <body>
        <h1>test</h1>
        <div class="bound"></div>
        <script src='http://cdn.ractivejs.org/latest/ractive.js'></script>

        <script>
            var binding = new Ractive({
                el: document.querySelector('.bound'),
                data: {
                    name: 'mike',
                    swaggify: function(string) {return 'SWAG'+string}
                },
                template: '<p>Hello, {{ swaggify(name) }}!</p>'
            })

            binding.reset().then(function(){
                binding.data.name = 'steve'
            })
        </script>
    </body>

强制性的 JSFiddle

4

1 回答 1

3

When you call ractive.reset(), it replaces the data object - in this case, that includes the swaggify function. If you put it back, it works fine: http://jsfiddle.net/rich_harris/49JAK/

(Note that I've put the update code immediately after the call to binding.reset() - the changes happen synchronously, the .then() just allows you to schedule a function for when any transitions have completed. It's Promises/A+ compliant so the code inside .then() will always be asynchronous - in some situations that can cause flicker, so sync > async where possible.)

That's probably not what you want though - you want to be able to treat the data and the formatters differently. A good approach is to put the formatters on the prototypal data object that all others inherit from:

var helpers = Ractive.defaults.data; // Ractive.defaults === Ractive.prototype
helpers.swaggify = function(string) {return 'SWAG'+string};

var binding = new Ractive({
  el: document.querySelector('.bound'),
  data: {
    name: 'mike',
    swaggify: function(string) {return 'SWAG'+string}
  },
  template: '<p>Hello, {{ swaggify(name) }}!</p>'
})

Demo of this approach here: http://jsfiddle.net/rich_harris/chYD6/.

于 2014-08-01T12:13:09.687 回答