2017-10-11 57 views
2

我使用AngularFire2和我做這樣的事情:是否有一個flatMap等價物返回內部可觀察值?

// assume loggedInUserId is Observable<string> 
var firebaseList = loggedInUserId 
    .flatMap((userId) => this.db.list(this.firebaseRoot.child(userId))) 

this.db.list返回與方便的功能FirebaseListObservable<any[]>pushdelete等,但flatMap只返回Observable<any[]>所以我沒有得到訪問他們。

有沒有相當於flatMap那會返回FirebaseListObservable?或者那是不可能的?

+0

這是不可能的。在[this]中看到我的評論(https://github.com/angular/angularfire2/issues/1008#issuecomment-304510732)AngularFire2問題的解釋。請隨時修改您的問題和[自我回復](https://stackoverflow.com/help/self-answer)。 – cartant

回答

0

您可以嘗試使用地圖,而是會保留從火力

編輯的原始觀察到的:也許是鑄造的答案

var firebaseList = loggedInUserId.flatMap((userId) => 
this.db.list(this.firebaseRoot.child(userId))) as FirebaseListObservable<any> 
firebaseList.flatMap(items=>ob.push({foo:'bar'})).subscribe() 

對於改變打字請參見右這 How do I use .take on FirebaseListObservable?

+0

的確如此,但後來我得到了'Observable'的'Observable's,這意味着我需要做'x |異步|異步「和各種其他怪異。我會研究這個鏈接,但我可以用'as'來投射它... –

+0

你說得對,也許使用flatmap投射和壓平它會工作 –

+1

恐怕不是:/ cast with'as '並且登錄控制檯仍然會產生一個'Observable'。 –

0

這是否有幫助?

loggedInUserId.subscribe(userId => { 
    var firebaseList = this.db.list(this.firebaseRoot.child(userId)) 
    // do stuff with the list 
} 

編輯

是否switchMap返回你所需要的類型?

const firebaseList = 
    loggedInUserId.switchMap(userId => 
    this.db.list(this.firebaseRoot.child(userId)) 
) 
+0

是的,我看到了這種方法,但是我已經有了使用Firebase函數的類方法,我寧願讓它們保持簡單和同步,而不是每次都使用「訂閱」。 –

+0

那麼,範的建議使用'map()'(我已經使用訂閱)應該這樣做。我明白'返回OuterObservable.someOperator(outerVal => {return InnerObservable ...})模式將返回內部的類型。你幾乎有這個,所以也許操作員是不正確的。我會檢查理論。 –

+0

switchMap沒有運氣 - VS代碼告訴我它是'(local var)test:Observable '。我認爲@ cartant的評論可能是答案。 –

0

您可以創建一個轉換器

const mapToFirebaseListObservable = (source) => { 
    new FirebaseListObservable(observer => { 
    return source.subscribe({ 
     next(x) { observer.next(x); }, 
     error(err) { observer.error(err); }, 
     complete() { observer.complete(); } 
    }) 
    }) 
} 

var firebaseList = mapToFirebaseListObservable(
    loggedInUserId 
    .flatMap((userId) => this.db.list(this.firebaseRoot.child(userId))) 
) 

我還沒有嘗試過了一個完整的火力點安裝,使用它,所以你可能會得到一個錯誤newing了FirebaseListObservable,但我已經使用具有附加功能的Observable嘗試過它

const newObservable = new Observable(observer => { 
    ... 
}) 
newObservable['myFn'] =() => 'from myFn' 

並且該函數在輸出中存在且可調用。

編輯:這似乎也工作

const toInner = (source) => { 
    return source.operator && source.operator.project 
    ? source.operator.project() 
    : source 
} 

用法:

var firebaseList = toInner(
    loggedInUserId 
    .flatMap((userId) => this.db.list(this.firebaseRoot.child(userId))) 
) 

它也可以變成一個連鎖運營商

const toInner = function() { 
    const source = this 
    return source.operator && source.operator.project 
    ? source.operator.project() 
    : source 
} 
Observable.prototype.toInner = toInner; 

又見here爲Rxjs v5.50beta關於創建操作符的更改。

相關問題