gpt4 book ai didi

javascript - 在非 onionified Cycle.js 应用程序中使用 cycle-onionify

转载 作者:行者123 更新时间:2023-11-30 15:07:10 27 4
gpt4 key购买 nike

我可能在尝试一些愚蠢的事情,但我有一个足够大的 -onionified Cycle.js 应用程序,我正在尝试学习如何 onionify可行,所以我想将一个 onionified 组件嵌入到我原来的非 onion 应用程序中。

所以我有一个简单的洋葱就绪组件,increment/decrement example ,我有一个简单的非洋葱循环应用程序,“Hello Last Name”示例 — 我如何将两者混合在一起,以便在同一网页中一个接一个地拥有增量组件和 Hello 组件?

Counter.ts,洋葱就绪组件

import xs from 'xstream';
import run from '@cycle/run';
import { div, button, p, makeDOMDriver } from '@cycle/dom';

export default function Counter(sources) {
const action$ = xs.merge(
sources.DOM.select('.decrement').events('click').map(ev => -1),
sources.DOM.select('.increment').events('click').map(ev => +1)
);

const state$ = sources.onion.state$;

const vdom$ = state$.map(state =>
div([
button('.decrement', 'Decrement'),
button('.increment', 'Increment'),
p('Counter: ' + state.count)
])
);

const initReducer$ = xs.of(function initReducer() {
return { count: 0 };
});
const updateReducer$ = action$.map(num => function updateReducer(prevState) {
return { count: prevState.count + num };
});
const reducer$ = xs.merge(initReducer$, updateReducer$);

return {
DOM: vdom$,
onion: reducer$,
};
}

index.ts,非洋葱主应用

import xs, { Stream } from 'xstream';
import { run } from '@cycle/run';
import { div, input, h2, button, p, makeDOMDriver, VNode, DOMSource } from '@cycle/dom';

import Counter from "./Counter";
import onionify from 'cycle-onionify';
const counts = onionify(Counter);

interface Sources {
DOM: DOMSource;
}

interface Sinks {
DOM: Stream<VNode>;
}

function main(sources: Sources): Sinks {
const firstName$ = sources.DOM
.select('.first')
.events('input')
.map(ev => (ev.target as HTMLInputElement).value)
.startWith('');

const lastName$ = sources.DOM
.select('.last')
.events('input')
.map(ev => (ev.target as HTMLInputElement).value)
.map(ln => ln.toUpperCase())
.startWith('');

const rawFullName$ = xs.combine(firstName$, lastName$)
.remember();

const validName$ = rawFullName$
.filter(([fn, ln]) => fn.length > 0 && ln.length >= 3)
.map(([fn, ln]) => `${ln.toUpperCase()}, ${fn}`);

const invalidName$ = rawFullName$
.filter(([fn, ln]) => fn.length === 0 || ln.length < 3)
.mapTo('');

const name$ = xs.merge(validName$, invalidName$);

const vdom$ = name$.map(name =>
div([
p([
'First name',
input('.first', { attrs: { type: 'text' } }),
]),
p([
'Last name',
input('.last', { attrs: { type: 'text' } }),
]),
h2('Hello ' + name),
]),
);

return {
DOM: vdom$,
};
}

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

尝试

如果我将 run(main, ...) 替换为 run(counts, ...),正如 cycle-onionify 文档建议的那样应用程序,我只看到预期的计数器。

但是 counts,作为 onionify(Counter) 的输出,是一个函数,所以我不认为我可以在我的 `main( ).

同样,我认为我不能通过在 main 中调用 Counter() 来创建计数器组件,因为该函数需要 sources.onion 输入,而且我'我不确定如何创建类型为 StateSource.onion 字段。

问题

我如何在我的非洋葱化 main 中使用这个 Counter onion-ready 组件?

完整示例

完整示例可在 https://gist.github.com/fasiha/939ddc22d5af32bd5a00f7d9946ceb39 获得— 克隆它,npm install 获取必要的包,然后 make(运行 tscbrowserify 来转换TypeScript→JavaScript→浏览器化 JS)。

最佳答案

其实很简单。正如您所说,您可以在主程序中调用 Counter(),但是它没有 StateSource

解决方案是用onionify(Counter)()替换Counter():

function main(sources: Sources): Sinks {
//other main stuff

const vdom$ = //implementation here

const counterSinks = onionify(Counter)(sources);

const combinedVdom$ = xs.combine(vdom$, counterSinks.DOM)
.map(div). //Enclose with div

return {
DOM: combinedVdom$,
};
}

请注意,这只会使用 Counter 中的 DOM 接收器,因此如果您想在计数器中使用其他接收器,您还必须指定它们:

const counterSinks = onionify(Counter)(sources);

const combinedVdom$ = xs.combine(vdom$, counterSinks.DOM)
.map(div). //Enclose with div

return {
DOM: combinedVdom$,
HTTP: xs.merge(myOwnRequest$, counterSinks.HTTP)
//...
};

因为对每个接收器都这样做有点乏味,我在包 cyclejs-utils 中创建了一个助手:

const counterSinks = onionify(Counter)(sources);

const combinedVdom$ = xs.combine(vdom$, counterSinks.DOM)
.map(div). //Enclose with div

const ownSinks = { DOM: vdom$, /* ... */ };

return {
...mergeSinks(ownSinks, counterSinks)
DOM: combinedVdom$
};

我额外指定 DOM 的原因是 mergeSinks 在每个接收器上调用 merge,但是对于 DOM,您想使用 combine + map,将 DOM 组合到新的父 DOM 正是您想要使用它的方式.

关于javascript - 在非 onionified Cycle.js 应用程序中使用 cycle-onionify,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45580058/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com