【问题标题】:List and Isolate 3 Items in Cycle.js在 Cycle.js 中列出和隔离 3 个项目
【发布时间】:2016-07-25 21:37:44
【问题描述】:

作为一个新手,我正在尝试在 Cycle.js 中制作 包含 3 个项目的列表。但是代码有错误。 我制作了jsbin并将代码也放在了下面

http://jsbin.com/labonut/10/edit?js,output

问题:当我点击最后一个复选框时,它会添加新的复选框(我不想要),而旧的不会改变它的“开/关”标签。除了最后一个,其他的都没有反应。我做错了什么?

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

function List(sources) {

  sources.DOM
  var vdom$ = xs.fromArray([
    {text: 'Hi'},
    {text: 'My'},
    {text: 'Ho'}
  ])
    .map(x => isolate(ListItem)({Props: xs.of(x), DOM: sources.DOM}))
    .map(x => x.DOM)
    .flatten()
    .fold((x, y) => x.concat([y]), [])
    .map(x => div('.list', x));

  return {
    DOM: vdom$
  }
}

function ListItem(sources) {
  const domSource = sources.DOM;
  const props$ = sources.Props;

  var newValue$ = domSource
    .select('.checker')
    .events('change')
    .map(ev => ev.target.checked);

  var state$ = props$
    .map(props => newValue$
      .map(val => ({
        checked: val,
        text: props.text
      }))
      .startWith(props)
    )
    .flatten();

  var vdom$ = state$
      .map(state => div('.listItem',[
        input('.checker',{attrs: {type: 'checkbox', id: 'toggle'}}),
        label({attrs: {for: 'toggle'}}, state.text),
        " - ",
        span(state.checked ? 'ON' : 'off')
      ]));
  return {
    DOM: vdom$
  }
}


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

【问题讨论】:

    标签: cyclejs xstream-js


    【解决方案1】:

    稍微短一点的变体。

    第一行,获取 Items Dom 流数组。

    第二行,然后将流合并为一个流并将元素包装到父div中

    function List(sources) {
    
      var props = [
        {text: 'Hi'},
        {text: 'My'},
        {text: 'Ho'}
      ];
    
      var items = props.map(x => isolate(ListItem)({Props: xs.of(x), DOM: sources.DOM}).DOM);
    
      var vdom$ = xs.combine(...items).map(x => div('.list', x));
    
      return {
        DOM: vdom$
      }
    }
    

    【讨论】:

    • 我更喜欢这个答案!我在答案中添加了一个 es5 兼容版本。
    • 我建议您将此答案设为所选答案。我很乐意提供帮助(和学习),但我认为找到这个问题的人最好使用这个答案。
    • 好吧,stackoverflow 说,“你可以在 5 小时内接受你自己的答案”,太晚了,看起来像
    • 啊。我将您启发的版本移到了答案的顶部。
    【解决方案2】:

    Vladimir's answer 的启发,这是他答案的“老派”变体以及对我原来答案的改进:

    function List(sources) {
    
      const props = [
        {text: 'Hi'},
        {text: 'My'},
        {text: 'Ho'}
      ];
    
      var items = props.map(x => isolate(ListItem)({Props: xs.of(x), DOM: sources.DOM}).DOM);
    
      const vdom$ = xs.combine.apply(null, items)
        .map(x => div('.list', x));
    
      return {
        DOM: vdom$
      };
    }
    

    Old school JSBin demo


    (原始答案。)

    看来问题出在您的List 函数中。坦率地说,我不知道原因,但已经制定了另一种解决方案:

    function List(sources) {
    
      const props = [
        {text: 'Hi'},
        {text: 'My'},
        {text: 'Ho'}
      ];
    
      function isolateList (props) {
        return props.reduce(function (prev, prop) {
          return prev.concat(isolate(ListItem)({Props: xs.of(prop), DOM: sources.DOM}).DOM);
        }, []);
      }
    
      const vdom$ = xs.combine.apply(null, isolateList(props))
        .map(x => div('.list', x));
    
      return {
        DOM: vdom$
      };
    }
    

    JSBin demo

    这里的一个区别是我没有流式传输 props 对象中的项目。相反,我将数组传递给一个函数,该函数将 reduces 属性传递给列表项 vdom 流的数组,然后 applying 将该数组传递给 xstream combine 工厂。

    【讨论】:

    • 是的,你是对的,花点时间了解流程
    猜你喜欢
    • 2017-06-29
    • 2023-04-04
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2012-08-04
    相关资源
    最近更新 更多