你能 "hijack" 渲染 Ractive 模板的一部分吗?

Can you "hijack" rendering part of a Ractive template?

我有一个 "SuperSelect" 控件,目前作为 Ractive 组件实现,它通过搜索、过滤、扩展选项描述和其他各种好东西增强了常规下拉列表 select 列表。这通常工作得很好,除了我现在需要用大约 7,800 个选项填充这些 SuperSelects 之一,它变得 真的 慢,并且也减慢了页面的其余部分。问题似乎是 Ractive 的内部内存使用;如果我在 vanilla JS 中重新实现 SuperSelect,大部分问题都会消失。不幸的是,我看不到一个好方法来真正利用我更高效的 SuperSelect,而不是完全撕掉 Ractive 的每个使用的地方,这看起来就像把婴儿连同洗澡水一起倒掉一样。

所以,基本上,我需要一种方法将由其他代码管理的 DOM 块插入到 Ractive 模板的中间,同时仍然允许在更新相关键路径时通知控制代码通过包含的 Ractive 实例,据我所知 none 现有的 plugin/extension 方法非常符合要求。到目前为止,我想出了两个结合多个可能有效的插件方法的技巧:

  1. 结合适配器和装饰器。在这种情况下,装饰器将简单地用 SuperSelect 的 DOM 片段替换它所附加的任何元素。然后一个特殊的 SuperSelect 控制对象将被添加到 Ractive 实例的数据中,带有一个适配器,让它参与与模板其余部分的双向绑定,并独立地与装饰器代码通信以更新 SuperSelect DOM .

  2. 将装饰器与迷你组件组合在一起 ractive.observe。在这种情况下,装饰器将再次用 SuperSelect DOM 片段替换特定的模板元素,但它只会在组件中局部使用,该组件的模板只包含一个装饰元素。该组件将用作重置键路径根的一种方法,以便装饰器代码可以 observe 一组静态键路径,以便更新 SuperSelect DOM 的状态,而不管 SuperSelect 是如何嵌入的在更大的父活动实例中。

有没有更简单的方法来满足我的需求?

是的——您可以创建一个具有空 DOM 节点的组件,然后在观察处理程序中重新呈现其内容:

const SuperSelect = Ractive.extend({
  template: `
    <div><!-- we'll render this bit ourselves --></div>`,
  onrender () {
    const div = this.find( 'div' );
    this.observe( 'items', items => {
      // render the items however we want
    });
  }
});

更完整的演示在这里:http://jsfiddle.net/9w9rrr9s/