Cycle.js получает значение при нажатии кнопки

Я работаю над примером приложения списка задач, используя Cycle.js, и я столкнулся со следующей проблемой. Я пытаюсь обработать добавление нового элемента todo, когда пользователь нажимает кнопку Add, что работает нормально, но, с другой стороны, у меня есть поток, который предоставляет события изменения ввода текста, и в сочетании с потоком кликов он заставляет мое приложение добавлять новые элементы todo даже в случае изменения ввода текста, но кнопка "Добавить" не нажата, например, фокусировка. Какой подход в таких случаях? Могу ли я просто исключить todoChange$ stream и напрямую получить доступ к DOM из addClick$ stream, или это противоречит философии Cycle.js?

JS Bin: https://jsbin.com/wugawaheni/edit?js,console,output

const xs = xstream.default;
const {div, input, p, makeDOMDriver} = CycleDOM;

const intent = (DOMSource) => {
  const addClick$ = DOMSource.select('.add').events('click').map(ev => true);
  const todoChange$ = DOMSource.select('.todo').events('change').map(ev => ev.target.value);

  return { addClick$, todoChange$ };
};

const model = (addClick$, todoChange$) => {
  const add$ = addClick$.startWith(false);
  const todo$ = todoChange$.startWith('');

  return xs.combine(add$, todo$)
    .map((combined$) => combined$[1])
    .fold((todos, todo) => {
      todo.trim() && todos.push(todo);
      return todos;
    }, []);
};

const view = state$ => state$.map(todos => div([
  input({attrs: {type: 'text', class: 'todo'}}),
  input({attrs: {type: 'submit', value: 'Add', class: 'add'}}),
  div(todos.map(todo => p(todo)))
]));


const main = (sources) => {
  const { addClick$, todoChange$ } = intent(sources.DOM);
  const state$ = model(addClick$, todoChange$);
  const vdom$ = view(state$);

   return {
     DOM: vdom$
   };
 };

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

1 ответ

Решение

Включают xstream/extra/sampleCombine, затем...

Изменить:

//return xs.combine(add$, todo$)
return add$.compose(sampleCombine(todo$))

От sampleCombine документы:

Marble diagram:

--1----2-----3--------4--- (source)
----a-----b-----c--d------ (other)
     sampleCombine

-------2a----3b-------4d--

В этом случае add$ является source, а также todo$ является other, Результирующий поток испускается только тогда, когда other имеет значение И при значении source, Другими словами, поток испускается только тогда, когда source испускает, если значение доступно на other в сочетании с.

НОТА: sampleCombine не включен в значение по умолчанию xstream библиотека.

ESNextbin demo.

Другие вопросы по тегам