Как создать компоненты из массива JSON в цикле JS

Приведенный пример помеченного компонента слайдера с веб-сайта Cycle js. Как бы я взял JSON-массив информационных объектов ползунка и создать помеченный компонент ползунка для каждого объекта в массиве. например, если бы у меня был такой массив

let labelSliderArray =
[
   {
    label: 'Height',
    unit: 'in',
    min: 40,
    max: 84,
    init: 50
  },
  {
    label: 'Weight',
    unit: 'ibs',
    min: 40,
    max: 84,
    init: 50
  },

   {
    label: 'Age',
    unit: 'years',
    min: 10,
    max:  65,
    init: 20
  }

]

Как бы я сопоставить каждый объект метки с компонентом метки. Я попытался сопоставить каждый объект метки с IsolatedLabeledSlider, вот так

const {div, input, label, h2, makeDOMDriver} = CycleDOM;
const isolate = CycleIsolate;


function intent(DOM){

  return DOM.select('.slider').events('input')
    .map(ev => ev.target.value);
 };

function model(action$, props$){

   const intialValue$ = props$.map(props => props.init).first();
   const value$ = intialValue$.concat(action$)

   const state$ = Rx.Observable.combineLatest(value$, props$, 
    (value,props) => {
      return {
        label: props.label,
        unit: props.unit,
        min: props.min,
        max: props.max,
        value: value
      }
    }

   );

   return state$
};

function view(state$){
 return  state$.map( state =>
      div('.labled-slider',
          [
            label('.label', `${state.label}: ${state.value} ${state.unit}`),
            input('.slider', {type: 'range', min: state.min, max: state.max, valeu : state.value})
          ]
      )
    )
};

function LabeledSlider(sources) {
  const change$ = intent(sources.DOM);
  const state$  = model(change$, sources.props)
  const vtree$  = view(state$)
  return {
    DOM: vtree$
  };
};


const IsolatedLabelSlider = function (sources){
  return isolate(LabeledSlider)(sources)
}

function main(sources){

let labelSliderArray =  Rx.Observable.from(
[
   {
    label: 'Height',
    unit: 'in',
    min: 40,
    max: 84,
    init: 50
  },
  {
    label: 'Weight',
    unit: 'ibs',
    min: 40,
    max: 84,
    init: 50
  },

   {
    label: 'Age',
    unit: 'years',
    min: 10,
    max:  65,
    init: 20
  }

]);
let labelSinks = labelSliderArray.map(sProps => IsolatedLabelSlider({DOM: sources.DOM,  props:  Rx.Observable.of(sProps)}) )
let labelVtree$ = labelSinks.map(l => l.DOM)

 return  {
   DOM: labelVtree$
 };
}

const drivers = {
  DOM: makeDOMDriver('#app')
}

Cycle.run(main, drivers);

Но это не удалось, это только отрисовало последний объект в массиве, любая помощь была бы отличной

Вот пример с сайта Cycle JS

1 ответ

Решение

Начиная с примера Cycle.js и сосредотачиваясь на main функция, вот переделки для размещения элементов управления ползунка и значений, происходящих из массива:

function main(sources) {

  let labeledSliderArray = [
    {label: 'Weight', unit: 'kg',    min: 40,  max: 150, init: 70},
    {label: 'Height', unit: 'cm',    min: 140, max: 220, init: 170},
    {label: 'Age',    unit: 'years', min: 10,  max: 80,  init: 20}
  ];

  vtrees = labeledSliderArray.map(function (item) {
    const itemProps$ = Rx.Observable.of(item);  
    const itemSinks = IsolatedLabeledSlider({
      DOM: sources.DOM, props: itemProps$
    });
    return itemSinks.DOM;
  });

  const vtree$ = Rx.Observable.combineLatest(
    vtrees, (...vtreeargs) =>
      div(vtreeargs)
  );

  return {
    DOM: vtree$
  };
}

labeledSliderArray отображается и в этом цикле *Props$, *Sinks, а также *VTree$ обобщаются, то результирующий массив предоставляется combineLatest, Затем оператор es6 "параметры покоя" используется для предоставления списка результирующих vtree для гиперскрипта. div функция, составляющая финал vtree$ реактивный поток.

JSBin Demo

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