【问题标题】:RactiveJS - when is it safe to call find(...)RactiveJS - 什么时候调用 find(...) 是安全的
【发布时间】:2015-08-19 00:57:01
【问题描述】:

什么时候可以安全地调用 ractive 实例的 find(...) 方法并保证模板已经被渲染并且 DOM 元素可用?

背景:

我是 RactiveJS 的新手,正在用它构建我的第一个应用程序。我一直在实例化 Ractive 实例,然后在这些实例上调用诸如 find() 之类的方法来访问从我的模板呈现的元素。像这样的:

var ractive = new Ractive({ el: ..., template: ..., data: ..., etc });
var element = ractive.find('.some-template-element');

到目前为止,这一直运行良好,但我想知道我是否可能在这里遇到竞争条件,因为 ractive 似乎异步渲染模板。像上面这样编写代码是否安全,还是我需要将所有内容都移到这样的回调中?

ractive.on('complete', function() {
    var element = ractive.find('.some-template-element');
});

信息太多:

在实践中,当然,我所做的比这个简单的伪代码更复杂。我正在创建使用 Ractive 作为内部实现细节的“小部件”。现在,我创建了这些小部件,然后开始在它们上调用方法。但是,如果 Ractive 方法还没有准备好立即调用,我将需要重组我的小部件以公开回调/承诺,一旦我知道我的 ractive 已经创建并可以使用,就会被调用。

我无法在 RactiveJS documentation 中找到详细信息,说明何时可以安全地调用 Ractive 上的各种函数,但我希望我只是漏掉了一些东西。

【问题讨论】:

    标签: ractivejs


    【解决方案1】:

    假设您提供了el 选项,渲染与new Ractive 实例化同步进行。

    虽然您可以通过ractive.on( 'event', ... ) 订阅,但使用onevent 选项通常更方便且认知更容易:

    var log = [];
    
    var r = new Ractive({
      el: document.body,
      template: '#template',
      data: {
        log: log
      },
      components: {
        'child-component': Ractive.extend({
          template: '<span>child</span>',
          oninit: function() {
            log.push('child component init');
          },
          onrender: function() {
            var span = this.find('span');
            log.push('child component render find span:' + !!span);
          },
          oncomplete: function() {
            log.push('child component complete');
          }
        })
      },
      oninit: function() {
        log.push('parent view init');
      },
      onrender: function() {
        var div = this.find('div'),
          span = this.find('span');
        log.push('parent component render, find div: ' + !!div + ' find span: ' + !!span);
      },
      oncomplete: function() {
        log.push('parent component complete');
      }
    });
    
    // these won't fire becasue they already happened! 
    r.on('init', function() {
      log.push('view on("init"...)');
    });
    r.on('render', function() {
      log.push('view on("render"...)');
    });
    
    // this will fire because complete is always async.
    r.on('complete', function() {
      log.push('view on("complete"...)');
    });
    <script src='//cdn.jsdelivr.net/ractive/0.7.3/ractive-legacy.min.js'></script>
    <script src='//cdn.jsdelivr.net/ractive.transitions-fade/0.2.1/ractive-transitions-fade.min.js'></script>
    <script id='template' type='text/ractive'>
      <div intro='fade'>main view</div>
      <child-component/>{{#log}}
      <li>{{.}} {{/}}
    </script>

    【讨论】:

    • 谢谢,马蒂。 'complete' 事件是异步触发的,这让我大吃一惊。我假设在收到该事件之前,该实例尚未完成并准备好使用。很高兴听到事实并非如此。知道实例是同步渲染的肯定会让我的代码更简单!
    • 这是因为所有“转换后”API 都是基于承诺的,例如 ractive.set( 'foo', 'bar' ).then( () =&gt; { ... } );
    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多