Ответ HTTP Cycle.js печатается как неопределенный в DOM

Я пытаюсь распечатать результаты HTTP-запроса к DOM в Cycle.js. Прямо сейчас я просто пытаюсь перечислить результаты, но они в конечном итоге будут в выпадающем списке.

Я создаю поток...

const facilityRequest$ = xs.of({
  url: 'http://...',
  category: 'facility'
});

Затем выберите это...

 const facilityResponse$ = sources.HTTP
  .select('facility')
  .flatten()
  .map(res => res.body.data)
  .startWith([]);

Но когда я пытаюсь добавить результаты в топ вроде:

const vdom$ = form$.map(form =>
  div([
    facilityResponse$.map(res => p(res.id)),
  ])
);

Отображается как undefined в окне браузера.

Однако, если я добавлю слушателя и запишу ответ на консоль, он отобразит массив средств:

facilityResponse$.addListener({
  next: (res) => {
    console.log(res);
  }
})

2 ответа

Да! Вы нашли правильный способ обработки вашего потока массивов.

// CORRECT :)
const facilityVDom$ = facilityResponse$.map(facilities => // <- this is an array
  ul( // <- notice no brackets here, because you already have an array
    facilities.map(f => li(f.id)) // <- ...and array map returns an array
  )
);

Однако это не проблема со списками.

Потоковые потоки похожи на массивы с течением времени, и их полезно рассматривать как массивы, но они не являются массивами и не взаимозаменяемы с массивами. Используйте только потоки в контексте STREAM и используйте массивы только в контексте ARRAY - отсюда и проблема с вашей первой попыткой:

// WRONG :(
const vdom$ = form$.map(form =>
  div([ // <-- the `div` function can take an ARRAY of VDOMs as parameter
    facilityResponse$.map(res => p(res.id)), // <-- this is a STREAM, not a VDOM
  ])
);

Здесь у вас есть две ошибки: 1) вы использовали поток в контексте массива, и 2) вы обернули то, что, по вашему мнению, было взаимозаменяемо с массивом в массиве. Таким образом, параметр, который вы предоставили div Функция была массивом с одним элементом, и этот элемент был потоком, а не объектом VDOM.


Массив, предоставленный div (или аналогичная) функция должна содержать объекты VDOM (или функции, которые возвращают объекты VDOM). Такие как:

div( [ p('1'), p('2'), p('3') ] ) // OR

div( [1,2,3].map(ii => p(ii))   ) // OR

let arr = [1,2,3]
div( arr.map(ii => p(ii))       )

map Метод STREAM принимает функцию, и эта функция переключает вас из контекста потока. Вы можете использовать потоки внутри этой функции, но они, как правило, бесполезны и никогда не взаимозаменяемы с массивами.

stream$.map(         // <- stream
  function (elem) {  // <- leaving stream

    // regular javascript here
    // transform each element of the stream
    // and return it to the stream
    return elem
  }
)                    // <- back to stream

Оказывается, что списки, как известно, трудно обрабатывать с помощью cycle.js. Для этого вы можете использовать библиотеку https://github.com/cyclejs/collection или отобразить элементы массива и объединить их в один элемент (это зависит от того, что вы хотите с ним сделать).

Я решил свой конкретный случай с:

const facilityVDom$ = facilityResponse$.map(facilities => ul(facilities.map(f => li(f.id))));

Вот некоторые соответствующие обсуждения:

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