列出并隔离 Cycle.js 中的 3 项
List and Isolate 3 Items in Cycle.js
作为新手,我正在尝试在 Cycle.js 中制作 包含 3 个项目的列表 。但是代码有错误。
我制作了jsbin并将代码放在下面
http://jsbin.com/labonut/10/edit?js,output
问题:当我点击最后一个复选框时,它会添加新的复选框(我不想要),而旧的不会改变它 "ON/off"标签。也除了最后一个,全都没有反应。我做错了什么?
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')
});
受到 的启发,这是他的答案的 "old school" 变体以及对我原来答案的改进:
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$
};
}
(原始答案。)
看来问题出在您的 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$
};
}
这里的一个区别是我没有流式传输 props
对象中的项目。相反,我将数组传递给一个函数,该函数 reduce
将道具传递给列表项 vdom 流的数组,然后 apply
将该数组传递给 xstream combine
工厂.
稍微短一点的变体。
第 1 行,获取项目 Dom 流数组。
第 2 行,然后将流合并为一个流并将元素包装到父级中 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$
}
}
作为新手,我正在尝试在 Cycle.js 中制作 包含 3 个项目的列表 。但是代码有错误。 我制作了jsbin并将代码放在下面
http://jsbin.com/labonut/10/edit?js,output
问题:当我点击最后一个复选框时,它会添加新的复选框(我不想要),而旧的不会改变它 "ON/off"标签。也除了最后一个,全都没有反应。我做错了什么?
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')
});
受到
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$
};
}
(原始答案。)
看来问题出在您的 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$
};
}
这里的一个区别是我没有流式传输 props
对象中的项目。相反,我将数组传递给一个函数,该函数 reduce
将道具传递给列表项 vdom 流的数组,然后 apply
将该数组传递给 xstream combine
工厂.
稍微短一点的变体。
第 1 行,获取项目 Dom 流数组。
第 2 行,然后将流合并为一个流并将元素包装到父级中 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$
}
}