Javascript 如何使用Cycle.js创建动态、重复的元素列表?

Javascript 如何使用Cycle.js创建动态、重复的元素列表?,javascript,rxjs,cyclejs,Javascript,Rxjs,Cyclejs,在Cycle.js中,我试图创建一个视图,在给定一组数据点时呈现动态数量的组件。但是,我不知道如何创建重复视图 我已经把所有的东西都剥离到我认为应该如何工作的最基本的例子。希望有人能指出我遗漏了什么 /* Expected: Given an array of data objects, create the following DOM <div class="container"> <h1 class=".data">Elemen

在Cycle.js中,我试图创建一个视图,在给定一组数据点时呈现动态数量的组件。但是,我不知道如何创建重复视图

我已经把所有的东西都剥离到我认为应该如何工作的最基本的例子。希望有人能指出我遗漏了什么

/*
    Expected:
    Given an array of data objects, create the following DOM
    <div class="container">
        <h1 class=".data">Element 1</h1>
        <h1 class=".data">Element 2</h1>
        <h1 class=".data">Element 3</h1>
        <h1 class=".data">Element 4</h1>
        ...
    </div>

    Result:
    <div class="container">
        <h1 class=".data">Element 9</h1>
    </div>
*/

function view( data$ ){
    return Rx.Observable.of(
        div('.container', data$.map( data =>
            h1('.data', `Element: ${ data.id }`)
        ))
    );
}

function main( sources ) {

    // Create an array of objects
    const arr = [];
    for( let i = 0; i < 10; i++ ){
        arr.push({
            id: `id ${i}`
        })
    }

    // Convert array to an observable
    const data$ = Rx.Observable.from(arr);

    const vtree$ = view( data$ );

    return {
        DOM: vtree$
    };

}

const drivers = {
    DOM: CycleDOM.makeDOMDriver('#mountPoint')
};

Cycle.run( main, drivers );
/*
预期:
给定一个数据对象数组,创建以下DOM
要素1
要素2
要素3
要素4
...
结果:
要素9
*/
函数视图(数据$){
返回Rx.observative.of(
div('.container',data$.map(data=>
h1('.data','Element:${data.id}`)
))
);
}
主要功能(来源){
//创建一个对象数组
常数arr=[];
for(设i=0;i<10;i++){
arr.push({
id:`id${i}`
})
}
//将数组转换为可观察数组
常数数据$=Rx.可观测自(arr);
const vtree$=视图(数据$);
返回{
DOM:vtree$
};
}
常量驱动程序={
DOM:CycleDOM.makeDOMDriver('#mountPoint')
};
循环运行(主、驱动器);

您的阵列有10个项目,因此可观测对象将发射10个项目。可观测数据表示随时间变化的数据。所以你的观测值代表10个时间点。其中只有最新的将被使用。这就是为什么你只看到“元素9”

您可能希望创建一个只包含一项的可观察项,而不是将数组转换为可观察项:数组

Rx.Observable.from(arr)
更改为
Rx.Observable.just(arr)

下一个问题是查看功能:

function view( data$ ){
    return Rx.Observable.of(
        div('.container', data$.map( data =>
            h1('.data', `Element: ${ data.id }`)
        ))
    );
}
查看函数采用
data$
参数。将
数据$
读取为
数据流
数据流
。所以你的函数接受一个流 到目前为止,这是正确的

但是现在您正在通过
Observable.of
创建一个新的Observable。那不是你想做的。相反,您可能只想将
数据$
(即数据流)转换为虚拟DOM节点流:

function view( data$ ){
    return data$.map( data =>
        // here you should return a virtual DOM node
    )
}
请记住:
data$
是随时间变化的数据。对于每个时间点,您都有一些数据。对于每个时间点,您都需要一些DOM树

function view( data$ ){
    return data$.map( data =>
        div('.container', 
          // data is not a single of your items but the whole array of items
          // hence we can map over it and transform each item into a child nod:
          data.map((item) => div('.item', item.id))
        )
    )
}
注意:
data$.map
与data.map非常不同。第一个变换/映射一个可观测的数组,第二个变换/映射一个经典数组

奖金:


您的阵列有10个项目,因此可观测对象将发射10个项目。可观测数据表示随时间变化的数据。所以你的观测值代表10个时间点。其中只有最新的将被使用。这就是为什么你只看到“元素9”

您可能希望创建一个只包含一项的可观察项,而不是将数组转换为可观察项:数组

Rx.Observable.from(arr)
更改为
Rx.Observable.just(arr)

下一个问题是查看功能:

function view( data$ ){
    return Rx.Observable.of(
        div('.container', data$.map( data =>
            h1('.data', `Element: ${ data.id }`)
        ))
    );
}
查看函数采用
data$
参数。将
数据$
读取为
数据流
数据流
。所以你的函数接受一个流 到目前为止,这是正确的

但是现在您正在通过
Observable.of
创建一个新的Observable。那不是你想做的。相反,您可能只想将
数据$
(即数据流)转换为虚拟DOM节点流:

function view( data$ ){
    return data$.map( data =>
        // here you should return a virtual DOM node
    )
}
请记住:
data$
是随时间变化的数据。对于每个时间点,您都有一些数据。对于每个时间点,您都需要一些DOM树

function view( data$ ){
    return data$.map( data =>
        div('.container', 
          // data is not a single of your items but the whole array of items
          // hence we can map over it and transform each item into a child nod:
          data.map((item) => div('.item', item.id))
        )
    )
}
注意:
data$.map
与data.map非常不同。第一个变换/映射一个可观测的数组,第二个变换/映射一个经典数组

奖金:


Cycle有一个收集模块。它获取对象数组流并将它们隔离。我用npm获得这些模块,用webpack部署

从'@Cycle/xstream run'导入周期;
从'@cycle/Collection'导入集合;
从'@cycle/dom'导入{div,h1};
从'@cycle/dom'导入{makeDOMDriver};
从“xstream”导入xs;
函数视图(comb$){
返回comb$.debug('view').map(tup=>{
const item=tup[0];
const clicked=tup[1];
返回div('.container',[h1('.data','Element:${item.id}单击:${clicked}`]);
});
}
/*项目组成*/
功能项(来源){
const intent$=sources.DOM//DOM上的事件仅限于接收器DOM上的事件
.select('div')
.events('click').mapTo('yes').startWith('no').debug('item clicks');
返回{
DOM:view(xs.combine(sources.itemjajaja,intent$))
};
}
主要功能(来源){
常数arr=[];
for(设i=0;i<10;i++){
arr.push(
//集合将obj添加到源的方式很奇怪
//这就是我的工作
{id\u to\u集合:i,//集合使用的标识符
itemJaJa:{
id:`id${i}`
}
} );
}
const items=Collection.gather(Item,sources,xs.of(arr),'id_to_Collection');
const vtrees$=Collection.pull(items,item=>item.DOM);
返回{
DOM:vtrees$.map(itemDomList=>div('.top',itemDomList)),
};    
}
警察司机={
DOM:makeDOMDriver(“#应用程序”)
};

循环运行(主、驱动器)循环有一个采集模块。它获取对象数组流并将它们隔离。我用npm获得这些模块,用webpack部署

从'@Cycle/xstream run'导入周期;
从'@cycle/Collection'导入集合;
从'@cycle/dom'导入{div,h1};
从'@cycle/dom'导入{makeDOMDriver};
从“xstream”导入xs;
函数视图(comb$){
返回comb$.debug('view').map(tup=>{
const item=tup[0];
const clicked=tup[1];
返回div('.container',[h1('.data','Element:${item.id}单击:${clicked}`]);
});
}
/*项目组成*/
功能项(来源){
const intent$=sou