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

gar*_*uan 0 javascript rxjs cyclejs

使用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 );
Run Code Online (Sandbox Code Playgroud)

Las*_*rte 6

您的数组有10个项目,因此observable将发出10个项目.Observable表示随时间变化的数据.所以你的观察代表了10个时间点.其中只使用最新的.这就是为什么你只看到"元素9".

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

更改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 }`)
        ))
    );
}
Run Code Online (Sandbox Code Playgroud)

您的视图函数采用data$参数.读data$data streamstream of data.所以你的函数接收到一个流到目前为止是正确的.

但是现在你正在创建一个新的Observable via Observable.of.这不是你想要做的.相反,您可能只想将data$- 即数据流 - 转换为虚拟DOM节点流:

function view( data$ ){
    return data$.map( data =>
        // here you should return a virtual DOM node
    )
}
Run Code Online (Sandbox Code Playgroud)

记住: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))
        )
    )
}
Run Code Online (Sandbox Code Playgroud)

注意:data$.map与data.map非常不同.第一个变换/映射一个可观察的,后一个变换/映射一个经典的数组.

奖金:

for( let i = 0; i < 10; i++ ){
     arr.push({
        id: `id ${i}`
     })
 }
Run Code Online (Sandbox Code Playgroud)

您正在以程序方式创建阵列.您可能更喜欢创建大小为10的数组并将其转换为包含项目的数组的功能方法:

Array.apply(Array, {length: 10}).map(
    (_,index) => ({id: `id: ${index}`})
)
Run Code Online (Sandbox Code Playgroud)