你能“劫持”渲染Ractive模板的一部分吗?

时间:2016-06-23 06:11:41

标签: javascript ractivejs

我有一个“SuperSelect”控件,目前作为Ractive组件实现,它通过搜索,过滤,扩展选项描述和各种其他好东西来增加常规下拉选择列表。这通常非常有效,除了我现在需要用大约7,800个选项填充其中一个SuperSelect,并且它真的慢,并且还减慢了页面的其余部分。问题似乎是Ractive的内部内存使用情况;如果我在vanilla JS中重新实现SuperSelect,大部分问题都会消失。不幸的是,我看不出一个好的方法来实际使用我的效率更高的SuperSelect,而不会完全撕掉Ractive每个使用过的地方,这似乎就像把洗澡水扔进婴儿一样。

因此,基本上,我需要一种方法将由其他代码管理的一大块DOM插入到Ractive模板的中间,同时仍然允许在包含Ractive实例更新相关密钥路径时通知控制代码,并且据我所知,现有的插件/扩展方法都不符合要求。到目前为止,我已经提出了两种可能有效的插件方法:

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

  2. 将装饰器与迷你组件和ractive.observe组合在一起。在这种情况下,装饰器将再次使用SuperSelect DOM片段替换特定模板元素,但它只能在组件中本地使用,该组件的模板除了一个装饰元素之外什么都不包含。该组件将作为重置密钥路径根的一种方法,以便装饰器代码可observe一组静态密钥路径,以便更新SuperSelect DOM的状态,无论SuperSelect如何嵌入更大的父级中ractive instance。

  3. 有没有更简单的方法来做我需要的事情?

1 个答案:

答案 0 :(得分:2)

是 - 您可以使用空DOM节点创建一个组件,并在observe处理程序中重新呈现其内容:

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/