Как включить два потока из одного события DOM

Форма имеет кнопку Сохранить. При щелчке он должен перенаправить на другой компонент и сохранить данные формы. Но маршрутизатор $ stream использует событие click, оставляя сокет $ stream без события, на которое нужно воздействовать. В приведенном ниже коде 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')

  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() кажется, добивается цели, но документация говорит, что она существует

разрешить одну вещь: круговая зависимость потоков

Это очень простой вариант использования. Такое ощущение, что мне не хватает чего-то фундаментального. Помощь приветствуется.

2 ответа

Решение

Это был неправильно заданный вопрос. см. комментарий...

Дублировать saveClick$ перед отправкой router$,

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))}`),
Другие вопросы по тегам