我如何知道组件的 DOM 何时更新并在 Active 中完成转换?



我正在尝试将IScroll库封装到Racive组件中。当组件的DOM发生变化并完成任何转换时,是否有一种方法可以得到通知,以便我可以更新滚动条?我看到了以下方法来实现这一点:

  1. 显式声明(组件模板的)依赖项,如

    <Scroll context="{{...}}" > </Scroll>
    

    我可以观察到context变量,但仍然无法等待转换完成。

  2. 修补Racive.set(),使其在使用时发出自定义事件:

    // Broadcast promise returned by `set`.
    var oldset = Ractive.prototype.set;
    Ractive.prototype.set = function () {
      var ret = oldset.apply(this, arguments);
      this.fire('set', ret);
      return ret;
    };
    

    然后,在组件的初始化代码中,我可以订阅set事件:

    this._parent.on('set', function (ret){
        ret.then(update);
    });
    

    这将不适用于Ractive.push()和其他方法。此外,这将通知我的组件set执行某些操作所做的所有更改,而不仅仅是那些影响组件DOM的更改。最后,我必须使用this._parent显式引用组件的父级,这意味着我的组件不能嵌套。

那么,在Racive中有更好的方法来实现这一点吗?

初始化选项允许oncomplete(或ractive.on(如果您愿意,可以使用'complete'…)进行初始渲染。看见http://docs.ractivejs.org/latest/lifecycle-events

所有的数据修改方法setanimatepushslice等都返回一个promise,在DOM更新和转换完成之前不会调用该promise。

下面是一个简单的例子(http://jsfiddle.net/ctfyes7t/):

{{#if show}}
    <li intro='fade:{ duration: 2000 }'>ta da!</li>
{{/if}}
r.set('show', true).then(function(){
    // called when fade intro complete
});

问题可以从另一个方向解决:可以使用MutationObserver观察DOM特定部分的变化。

因此,我最终采用了以下方法来包装外部小部件:基本上,我们使用intro转换获得组件的顶部节点(并初始化第三方代码),然后在oncomplete回调寄存器观察器中使用类似的东西:

this.observer = new MutationObserver(update);
this.observer.observe(this.node, {
    childList: true,
    subtree: true,
    characterData: true,
    attributes: true, // transitions may change attributes
});

其中函数CCD_ 13更新第三方小部件。

这是该组件的源代码。

最新更新