【问题标题】:how to power two streams from one DOM event如何从一个 DOM 事件中为两个流供电
【发布时间】:2017-06-17 23:50:02
【问题描述】:

表单有一个保存按钮。当点击它应该路由到另一个组件并保存表单数据。但是 router$ 流消耗了 click 事件,使 socket$ 流没有事件可以采取行动。在下面的代码中,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() 似乎在起作用,但文档说它存在

允许一件事:流的循环依赖

这是一个非常基本的用例。感觉就像我错过了一些基本的东西。感谢您的帮助。

【问题讨论】:

    标签: cyclejs xstream-js


    【解决方案1】:

    在发送到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))}`),
    

    【讨论】:

    • 非常感谢@bloodyKnuckles 的回复!我不会接受它,因为我的问题一开始就不正确。我的问题是我试图生成两个流,其中一个是路由器流。在另一个流可以继续之前,它导致了完全的 vdom 重组。这是对幕后发生的事情缺乏了解。但是你的回答把我推向了正确的方向。非常感谢。再次感谢!
    【解决方案2】:

    这是一个错误的问题。看评论...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多