2016-03-21 19 views
-1

merge veya combineLatest işlevine hangi akışın geleceğini, yalnızca yeni akışın çalışacağı şekilde tanımlamak için bazı en iyi uygulama önerileri arıyorum.RxJS: birleştirilmiş akışta akış kaynağını tanımlamak için doğru desenler?

Bir TODO uygulaması bağlamında, gelen akışları ekleme ve kaldırma işlemlerine sahibim ve bunları birleştirmek istiyorum; böylece liste düzenlemem, tek bir akış içinde vatansız bir şekilde gerçekleşebilir. Çıktı hem add (concat) hem de remove (filter) olaylarını entegre eden bir listedir, aksi takdirde tüm add veya remove olaylarını içeren ve böylece sonsuz bir şekilde büyümekte olan diğer akışlarla sonuçlanıyor gibi görünüyorsunuz. karşılaşılan

problemler şunlardır:

  • gelen olan akış göstermez merge kullanılarak combineLatest kullanarak
  • , hangi akışın abone akışını tetiklediğini göstermez, bu nedenle yalnızca bu akışla ilgili işlemleri gerçekleştiremezsiniz.
  • withLatestFrom kullanarak, withLatestFrom giriş kaynağını güncelleştirmeyen yeni bir liste ile sonuçlanır, böylece bir sonraki akış bu listeyle ilgilenmiyorsa bu listeye abone olmazsa, liste eşitlenmez (veya her yeni listeniz ondan önce olan, daha önce olanlar için her dönüşüme gereksiz yeniden adım atmaya neden olur ...). Bir şekilde alt optimum görünüyor

Şu bulundu yaklaşımlar şunlardır:

  • Döngüsü JS YAPILACAK uygulaması açıkça ben sanırdım tanımlama için erken akışları, oluşturulan nesnelere doğrudan type özelliklerini atar gerektiği Akışların nereden geldiğini doğrudan belirleyen RxJS yöntemlerini kullanmaktan kaçınılmalıdır?
  • hem ekleyebilir ve olayları kaldırmak, hala güncellenmektedir ediliyordu gelen akışını tanımlayabilir için böylece merge kullanırken http://www.jisaacks.com/manipulating-rxjs-streams/ gelen öneri alma ve ekleme akarsu ve [null, {addItem}] ve [removeItem, {null}] için çıkarılması akışları çıktısını, öyle ki bölme ben tek bir akışta hem ekleme hem de çıkarma işlemini gerçekleştirebilir (ancak sonra geçiş olayları eklemek istiyorum, vb.), ya da diğer potansiyel akımların farkında olan akış çıktıları oluşturmaya ihtiyacım olduğu için bu tam olarak doğru görünmüyor (biten) ile [boş, null, myOutput, null, vb anlamsız].

Herhangi iyi uygulama önerileri çok açıktır.

cevap

1

Bir akışın nereden geldiğini tanımlayan Rxjs yöntemi yoktur. Akarsular, üzerlerinde bir isim taşımamaktadır. Eğer istersen, kendini koymalısın. Bu iki yoldan hiç hoşlanmıyorsanız, onlara bir isim koymanın başka bir yolunu bulun. Sorunuz, bir nesneye bir tanımlayıcı koymak için en iyi uygulama hangisiyse, o zaman cevap, lanet nesnenin üzerine bir tanımlayıcı konur.

source1.map(label('remove')).merge(source2.map(label('add'))) 

ama sen bunu nasıl bu oldukça olduğunu lütfen gerçekten, yapın: Ben olarak kullanmak

function label(identifier){return function (x){var obj={};obj[identifier]=x;return obj;};} 

aşağıdaki gibidir:

Ben şahsen lehine yolu curried fonksiyonu geçer küçük bir sorun, bence.

+0

Çok teşekkürler. Tecrübenizde küçük görünebilir ama sadece özel bir yol olduğunu fark ettim (özellikle de combineLatest kullanıldığında hangi özel akışın güncellendiğini tespit etmek için kaçırdım) (ve doğru Rx yolunda yapmıyordum). Bu yüzden, bunun doğru olması için gerçekten önemli olduğunu düşündüm ve doğru kalıp (yani sadece nesneye bir tanımlayıcı koymak), her yerde doğru yaklaşım olarak açıklığa kavuşturulmamıştır, bu yüzden benim sorumun neden aşağı oylandığından emin değilim. Her durumda, etiketleme işlevinizle birlikte 'birleştirmeyi 'kullanacağım, teşekkürler. – brokenalarms

1

Gereksiz kimlik işlemlerinden kaçınmak için birleştirmeden önce doğru akışı işleyebilirsiniz. Genel olarak akışlar ve fonksiyonel programlama ile, size yardımcı olacak araçlar olduğu takdirde-if yapılardan kaçınmaya çalışın. Genellikle, aramanın yapıldığı yere bakarak ve daha erken hareket ederek bunu önleyebilirsiniz.

İşte bir örnek. Liste işlemleri, en önemli parçaların görünür olmasını sağlamak için sadece sahte.

let listSubject: Rx.Subject<Item[]> = new Rx.BehaviourSubject<Item[]>([]); 
let addObs: Rx.Observable<Item[]> = initAddObs(); 
let removeObs: Rx.Observable<Item[]> = initRemoveObs(); 

Rx.Observable 
    .merge([ 
    addObs.map(items => (list: Item[]) => list.concat(items)), 
    removeObs.map(items => (list: Item[]) => list.filter(items)) 
    ]) 
    .withLatestFrom(listSubject, (operation, list) => operation(list)) 
    .subscribe(listSubject) 

listesi için abone oldukları zaman bu kadar herkes olursa olsun son durumu almak BehaviourSubject orada kullanılır. AddObs ve removeObs akışları, aynı imzası olan ve birleştirilebilen işlemlerle eşleştirilir. İşlem mevcut listeye göre yapıldıktan sonra sonucu tekrar listSubject'e geri döndürmeliyiz. Şimdi listSubject'e abone olabilirsiniz ve oradan çıkan güncel listeyi alacaksınız.

+0

Girdiğiniz için teşekkürler, bu gerçekten de budur ve bundan sonra öğrendim ki .WithLatestFrom her bir eyaleti hafızaya aldığını ve çağrıldığının, ilk başta düşündüğüm gibi zincirleme için herşeyi 'tetiklemediğini' söylüyor. Ne yazık ki soru çoktan cevaplandırıldı ve ben de bu şekilde işaretledim, bu yüzden de sizin de doğruyu sorsa da sorularınızı yanıtlarken işaretleyemiyorum. – brokenalarms

İlgili konular