0

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 );
4

2 に答える 2

6

配列には10個のアイテムがあるため、オブザーバブルは10個のアイテムを発行します。オブザーバブルは、経時的なデータを表します。したがって、オブザーバブルは 10 の時点を表します。それらのうち、最新のもののみが使用されます。そのため、「要素 9」しか表示されていません。

配列をオブザーバブルに変換する代わりに、1 つのアイテムのみを含むオブザーバブルを作成したい場合があります: 配列です。

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$パラメーターを取ります。またはと読みdata$ます。したがって、関数はストリームを受け取ります。これはこれまでのところ正しいです。data streamstream of data

しかし今、あなたは を介し​​て新しい Observable を作成していますObservable.of。それはあなたがしたいことではありません。data$代わりに、つまりデータのストリームを仮想 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$.mapdata.map とは大きく異なります。最初はオブザーバブルを変換/マップし、後で古典的な配列を変換/マップします。

ボーナス:

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

手続き型の方法で配列を作成しています。サイズ 10 の配列を作成し、それを項目を含む配列に変換する機能的な方法を好むかもしれません。

Array.apply(Array, {length: 10}).map(
    (_,index) => ({id: `id: ${index}`})
)
于 2016-03-20T18:00:12.740 に答える
0

Cycle には Collection モジュールがあります。オブジェクトの配列のストリームを取り、それらを分離します。これらのモジュールを npm で取得し、webpack でデプロイします。

import Cycle from '@cycle/xstream-run';
import Collection from '@cycle/collection';
import {div,h1} from '@cycle/dom';
import { makeDOMDriver } from '@cycle/dom';
import xs from 'xstream';

function view( comb$ ){
  return comb$.debug('view').map( tup =>{
    const item = tup[0];
    const clicked = tup[1];
    return div('.container', [ h1( '.data', `Element: ${item.id} clicked: ${clicked}`)]);
  });
}

/* Item Component */
function Item ( sources ){
  const intent$ = sources.DOM   //Events on DOM are limited to only ones on sink DOM
    .select('div')
    .events('click').mapTo('yes').startWith('no').debug('item clicks');
      
  return {
    DOM: view( xs.combine( sources.itemJaJa, intent$) )
  };
}

function main(sources) {

  const arr = [];
  for( let i = 0; i < 10; i++ ){
    arr.push(
      //The way Collection add the obj to the source is odd
      //this is what's worked for me
      { id_to_collection: i, //identifier used by collection
        itemJaJa:{ 
          id: `id ${i}`
        }
      } );
  }
  
  const items = Collection.gather(Item, sources, xs.of( arr),'id_to_collection'  );  
  const vtrees$ = Collection.pluck( items, item=>item.DOM);  
  return {
    DOM:  vtrees$.map( itemDomList => div('.top',itemDomList)),
  };    
}

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

Cycle.run(main, drivers);

于 2017-02-08T22:28:28.980 に答える