是否有一个flatMap等价物返回内部可观察值?

是否有一个flatMap等价物返回内部可观察值?

问题描述:

我使用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

您可以尝试使用地图,而是会保留从火力

编辑的原始观察到的:也许是铸造的答案

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'。 –

这是否有帮助?

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的评论可能是答案。 –

您可以创建一个转换器

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关于创建操作符的更改。