5

我想使用 Foundation 的显示插件在 Cycle.js 应用程序中显示一个不错的模式。

在玩了几个小时的 Webpack 和它的配置之后,我想出了如何将 Foundation 的 js 正确地导入到我的(es6)应用程序中。

但是,由于我处理的是虚拟dom,所以在初始化基础的js时,实际的html是不存在的。

这是我的组件的代码:

import Rx from 'rx';
import {div} from '@cycle/dom';

import $ from 'jquery';
import {foundation} from 'foundation-sites/js/foundation.core';
import 'foundation-sites/js/foundation.util.keyboard';
import 'foundation-sites/js/foundation.util.box';
import 'foundation-sites/js/foundation.util.triggers';
import 'foundation-sites/js/foundation.util.mediaQuery';
import 'foundation-sites/js/foundation.util.motion';
import 'foundation-sites/js/foundation.reveal';

require('./styles/configuration-modal.scss');

function ConfigurationModal(sources) {

    const values$ = sources.props$;

    const vtree$ = Rx.Observable.just(1).map(() => {
        return div(
            '#config-modal.reveal',
            {attributes: {
                'data-reveal': ''
            }},
            ['hello']
        );
    });

    return {
        DOM: vtree$,
        values$
    };
}

$(function() {
    $.fn.foundation = foundation;
    $(document).foundation();
});

export default ConfigurationModal;

我的 main.js:

import Rx from 'rx';
import Cycle from '@cycle/core';
import {makeDOMDriver, div} from '@cycle/dom';
import ConfigurationModal from './components/ConfigurationModal/index';

require('./styles/index.scss');

function main(sources) {
    const props$ = Rx.Observable.of({
        pomodoroDuration: 25 * 60,
        shortBreakDuration: 5 * 60,
        longBreakDuration: 15 * 60
    });
    const configurationModal = ConfigurationModal({
        DOM: sources.DOM,
        props$
    });

    return {
        DOM: configurationModal.DOM,
    };
}

Cycle.run(main, {
    DOM: makeDOMDriver('#app')
});

现在,如果我$(document).foundation()在应用程序初始化后在控制台中运行,事情就会按预期工作。但是在app代码中,由于dom是虚拟的,实际的html还没有被注入,所以什么都没有出现。

在应用程序完全初始化并实际填充 dom 后,我如何运行 js 代码?

4

1 回答 1

12

In Cycle, there's a useful feature of the DOM driver that allows you to subscribe to updates for elements.

In this case, you can run code after the app starts up like this:

DOM
 .select(':root')
 .element()
 .take(1)
 .subscribe((element) => $(document).foundation())

You could add that to your main, and that should solve your problem.

However, in Cycle it's idomatic to encapsulate all of your subscribes in drivers, as they're usually side effects. In this case, you can make a driver to start Foundation, like so:

function startFoundation () {
  $(document).foundation();
}

function foundationDriver(sink$) {
  return sink$.take(1).subscribe(startFoundation);
}

And in your main.js:

function main(sources) {
    // ...

    const startup$ = sources.DOM.select(':root').element().take(1);

    return {
        DOM: configurationModal.DOM,

        FoundationStartup: startup$
    };
}

Cycle.run(main, {
    DOM: makeDOMDriver('#app'),
    FoundationStartup: foundationDriver
});
于 2016-04-11T08:42:38.940 回答