0

ばかげたことをやってみたり、Cycle.js をいじったりしているだけです。そして問題に直面しています。基本的にはボタンのみです。クリックすると、場所がランダムなハッシュに移動して表示されると想定されます。事前定義されたルートがないばかげたルーターのようなものです。すなわち。ルートは動的です。繰り返しますが、これは実用的なものではありません。私はいくつかのものをいじって、Cycle.js を学ぼうとしています。しかし、「追加」ボタンをクリックすると、以下のコードがクラッシュします。ただし、場所は更新されます。実際に「#/asdf」に移動すると、正しいコンテンツが「Hash: #/asdf」で表示されます。フローがエラーでクラッシュする理由がわからない:

render-dom.js:242 TypeError: undefined のプロパティ 'subscribe' を読み取れません(…)

import Rx from 'rx';
import Cycle from '@cycle/core';
import { div, p, button, makeDOMDriver } from '@cycle/dom';
import { createHashHistory } from 'history';
import ranomdstring from 'randomstring';

const history = createHashHistory({ queryKey: false });

function CreateButton({ DOM }) {
  const create$ = DOM.select('.create-button').events('click')
    .map(() => {
      return ranomdstring.generate(10);
    }).startWith(null);

  const vtree$ = create$.map(rs => rs ?
    history.push(`/${rs}`) :
    button('.create-button .btn .btn-default', 'Add')
  );

  return { DOM: vtree$ };
}

function main(sources) {
  const hash = location.hash;
  const DOM = sources.DOM;

  const vtree$ = hash ?
    Rx.Observable.of(
      div([
        p(`Hash: ${hash}`)
      ])
    ) :
    CreateButton({ DOM }).DOM;

  return {
    DOM: vtree$
  };
}

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

お手伝いありがとう

4

2 に答える 2

5

@cycle/history を使用してルートを変更することをお勧めします (関連する部分のみを表示)

import {makeHistoryDriver} from '@cycle/history'
import {createHashHistory} from 'history'

function main(sources) {
  ...
  return {history: Rx.Observable.just('/some/route') } // a stream of urls
}

const history = createHashHistory({ queryKey: false })
Cycle.run(main, {
  DOM: makeDOMDriver('#main-container'),
  history: makeHistoryDriver(history),
})
于 2016-03-28T23:04:12.360 に答える
2

あなたの関数では、エラーを引き起こす vtree にマッピングするのではなくCreateButton、クリックをマッピングしています:history.push()

function CreateButton({ DOM }) {
  ...
  const vtree$ = create$.map(rs => rs
    ? history.push(`/${rs}`) // <-- not a vtree
    : button('.create-button .btn .btn-default', 'Add')
  );
  ...
}

代わりに、do 演算子を使用して hashchange を実行できます。

function CreateButton({ DOM }) {
  const create$ = 
    ...
    .do(history.push(`/${rs}`)); // <-- here

  const vtree$ = Observable.of(
    button('.create-button .btn .btn-default', 'Add')
  );
  ...
}

ただし、関数型プログラミングでは、アプリケーション ロジックに対して副作用を実行するべきではなく、すべての関数は純粋なままでなければなりません。代わりに、すべての副作用はドライバーで処理する必要があります。詳細については、Cycle のドキュメントのドライバー セクションをご覧ください。

メッセージの最後に動作中のドライバーがジャンプするのを確認します。


さらに、main関数では、ストリームを使用して vtree をレンダリングしていませんでした。vtree$ = hash ? ... : ...アプリのブートストラップで 1 回しか評価されないため (メイン関数が評価され、すべてのストリームをまとめて「配線」するとき)、locationHash の変更に反応しませんでした。

main同じロジックを維持しながら、次のように vtree$を宣言すると改善されます。

const vtree$ = hash$.map((hash) => hash ? ... : ...)

これは、小さな locationHash ドライバーを使用した完全なソリューションです。

import Rx from 'rx';
import Cycle from '@cycle/core';
import { div, p, button, makeDOMDriver } from '@cycle/dom';
import { createHashHistory } from 'history';
import randomstring from 'randomstring';


function makeLocationHashDriver (params) {
  const history = createHashHistory(params);

  return (routeChange$) => {
    routeChange$
      .filter(hash => {
        const currentHash = location.hash.replace(/^#?\//g, '')
        return hash && hash !== currentHash
      })
      .subscribe(hash => history.push(`/${hash}`));

    return Rx.Observable.fromEvent(window, 'hashchange')
      .startWith({})
      .map(_ => location.hash);
  }
}

function CreateButton({ DOM }) {
  const create$ = DOM.select('.create-button').events('click')
    .map(() => randomstring.generate(10))
    .startWith(null);

  const vtree$ = Rx.Observable.of(
    button('.create-button .btn .btn-default', 'Add')
  );

  return { DOM: vtree$, routeChange$: create$ };
}

function main({ DOM, hash }) {
  const button = CreateButton({ DOM })
  const vtree$ = hash.map(hash => hash
    ? Rx.Observable.of(
        div([
          p(`Hash: ${hash}`)
        ])
      )
    : button.DOM
  )

  return {
    DOM: vtree$,
    hash: button.routeChange$
  };
}

Cycle.run(main, {
  DOM: makeDOMDriver('#main-container'),
  hash: makeLocationHashDriver({ queryKey: false })
});

PS:randomstring関数名にタイプミスがあります。例で修正しました。

于 2016-03-28T19:19:07.537 に答える