2016-03-20 11 views
0

Cycle.js ile bir dizi veri noktası verildiğinde dinamik bir bileşen sayısı veren bir görünüm oluşturmaya çalışıyorum. Ancak, tekrarlanan görüntülerin nasıl oluşturulacağını anlayamıyorum.Cycle.js ile dinamik, yinelenen öğeler listesini nasıl oluştururum?

Herşeyi, çalışmam için düşüncesinin en temel örneğine geri dönüştürdüm. Umarım birileri neyi kaçırdığımı gösterir.

/* 
    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); 

cevap

5

Dizininiz 10 öğeye sahiptir, böylece gözlenebilir 10 öğe yayar. Gözlenebilirler zaman içindeki verileri temsil eder. Gözlemlenebilir zaman içinde 10 puan temsil eder. Bunlardan sadece en son kullanılacaktır. Bu yüzden sadece "element 9" 'u görüyorsunuz.

Dizininizi gözlemlenebilir bir hale dönüştürmek yerine, yalnızca bir öğe içeren bir gözlemlenebilir oluşturmak isteyebilirsiniz: siz dizi.

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

görünümünüz işlevi data$ parametre alır:

Rx.Observable.just(arr)

sonraki konu haline Değişim Rx.Observable.from(arr) görüşünüz fonksiyonudur. data$'u data stream veya stream of data olarak okuyun. Yani işleviniz numaralı bir akışta gerçekleşiyor. Şimdiye kadar doğru.

Ancak şimdi Observable.of aracılığıyla yeni bir Gözlemlenebilir yaratıyorsunuz. Yapmak istediğin bu değil. verilerinizin akışında yani - - Onun yerine sadece data$ dönüştürmek isteyebilirsiniz sanal DOM düğüm akışına:

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

Unutmayın: data$ zamanla verilerinizi olduğunu. Zaman içindeki her nokta için bazı verileriniz var. Ve zaman içindeki her nokta için bazı DOM ağacına sahip olmak istersiniz.

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)) 
     ) 
    ) 
} 

dikkat: data$.map data.map çok farklıdır. Gözlemlenebilir ilk dönüşümler/haritalar, daha sonra klasik bir diziyi dönüştürür/eşler.

Bonus: Bir prosedürel bir şekilde diziyi oluştururken

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

. Bu kadar büyük 10 bir dizi oluşturma ve öğeleri içeren bir dizi haline dönüştürme fonksiyonel şekilde tercih edebilirsiniz:

Array.apply(Array, {length: 10}).map(
    (_,index) => ({id: `id: ${index}`}) 
) 
0

Döngüsü bir Koleksiyonu modülüne sahiptir. Nesne dizileri akışını alır ve onları yalıtır. Bu modülleri npm ile aldım ve webpack ile konuşlandırıyorum.

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

İlgili konular