5

Foundation の Reveal プラグインを使用して、Cycle.js アプリで素敵なモーダルを表示したいと考えています。

Webpack とその構成で何時間も遊んだ後、財団の js を自分の (es6) アプリに適切にインポートする方法を見つけました。

ただ、仮想DOMを扱っているので、Foundationの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()これで、アプリが初期化された後にコンソールで実行すると、期待どおりに動作します。しかし、アプリ コードでは、dom は仮想であり、実際の html はまだ挿入されていないため、何も表示されません。

アプリが完全に初期化され、dom が実際に設定された後、どうすれば js コードを実行できますか?

4

1 に答える 1

12

Cycle には、要素の更新を購読できる DOM ドライバーの便利な機能があります。

この場合、アプリの起動後に次のようにコードを実行できます。

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

それをメインに追加すると、問題が解決するはずです。

ただし、Cycle では、すべてのサブスクライブをドライバーにカプセル化することは、通常は副作用であるため、ばかげています。この場合、次のように、Foundation を開始するドライバーを作成できます。

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

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

そしてあなたの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 に答える