如何从一个 DOM 事件中为两个流供电
how to power two streams from one DOM event
表单有一个保存按钮。单击时它应该路由到另一个组件并保存表单数据。但是 router$ stream 消耗了 click 事件,而 socket$ stream 没有事件可以采取行动。在下面的代码中,saveClick$ 仅适用于 router$ 但不适用于 socket$。
import sampleCombine from 'xstream/extra/sampleCombine'
import parent from '../../../util/parent'
import xs from 'xstream'
import dataRequest from './dataRequest'
export default ({DOM, onion, props$}) => {
const saveClick$ = DOM
.select('.MetaNav__Save')
.events('click')
return {
router$: xs.merge(
DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$)),
saveClick$
.compose(sampleCombine(onion.state$))
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
socket$: saveClick$
.compose(sampleCombine(onion.state$))
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {
setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {
id
}
}`
}))
.startWith(dataRequest(props$))
}
}
如何获得由同一事件支持的两个流? imitate()
似乎可以解决问题,但文档说它存在
to allow one thing: circular dependency of streams
这是一个非常基本的用例。感觉好像我缺少一些基本的东西。感谢帮助。
在发送到 router$
之前复制 saveClick$
。
import sampleCombine from 'xstream/extra/sampleCombine'
import parent from '../../../util/parent'
import xs from 'xstream'
import dataRequest from './dataRequest'
export default ({DOM, onion, props$}) => {
const saveClick$ = DOM.select('.MetaNav__Save')
.events('click')
const saveClickSocket$ = saveClick$
.compose(sampleCombine(onion.state$))
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {id}}`
}))
.startWith(dataRequest(props$))
const allClick$ = xs.merge(
DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$)),
saveClick$,
.compose(sampleCombine(onion.state$))
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
return {
router$: allClick$,
socket$: saveClickSocket$
}
}
为清晰起见重构流构造:
const saveClick$ = DOM.select('.MetaNav__Save')
.events('click')
.compose(sampleCombine(onion.state$))
const cancelClick$ = DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$))
const saveClickSocket$ = saveClick$
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {id}}`
}))
.startWith(dataRequest(props$))
const allClick$ = xs.merge(
cancelClicks,
saveClick$,
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
这是一个错误的问题。看评论...
表单有一个保存按钮。单击时它应该路由到另一个组件并保存表单数据。但是 router$ stream 消耗了 click 事件,而 socket$ stream 没有事件可以采取行动。在下面的代码中,saveClick$ 仅适用于 router$ 但不适用于 socket$。
import sampleCombine from 'xstream/extra/sampleCombine'
import parent from '../../../util/parent'
import xs from 'xstream'
import dataRequest from './dataRequest'
export default ({DOM, onion, props$}) => {
const saveClick$ = DOM
.select('.MetaNav__Save')
.events('click')
return {
router$: xs.merge(
DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$)),
saveClick$
.compose(sampleCombine(onion.state$))
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
socket$: saveClick$
.compose(sampleCombine(onion.state$))
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {
setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {
id
}
}`
}))
.startWith(dataRequest(props$))
}
}
如何获得由同一事件支持的两个流? imitate()
似乎可以解决问题,但文档说它存在
to allow one thing: circular dependency of streams
这是一个非常基本的用例。感觉好像我缺少一些基本的东西。感谢帮助。
在发送到 router$
之前复制 saveClick$
。
import sampleCombine from 'xstream/extra/sampleCombine'
import parent from '../../../util/parent'
import xs from 'xstream'
import dataRequest from './dataRequest'
export default ({DOM, onion, props$}) => {
const saveClick$ = DOM.select('.MetaNav__Save')
.events('click')
const saveClickSocket$ = saveClick$
.compose(sampleCombine(onion.state$))
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {id}}`
}))
.startWith(dataRequest(props$))
const allClick$ = xs.merge(
DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$)),
saveClick$,
.compose(sampleCombine(onion.state$))
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
return {
router$: allClick$,
socket$: saveClickSocket$
}
}
为清晰起见重构流构造:
const saveClick$ = DOM.select('.MetaNav__Save')
.events('click')
.compose(sampleCombine(onion.state$))
const cancelClick$ = DOM.select('.MetaNav__Cancel')
.events('click')
.compose(sampleCombine(onion.state$))
const saveClickSocket$ = saveClick$
.map(([e, state]) => ({
messageType: 'graphql',
message: `mutation {setInfo(info: {title: "${document.getElementById('MetaTitle').value}", description: "${document.getElementById('MetaDescription').value}", favorite: ${document.getElementById('MetaFavorite').checked.toString()}}, id: "${state.id}") {id}}`
}))
.startWith(dataRequest(props$))
const allClick$ = xs.merge(
cancelClicks,
saveClick$,
)
.map(([e, state]) => `/album/${window.btoa(parent(state.id))}`),
这是一个错误的问题。看评论...