Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 在RxJS中使用Filter操作符 更新:我更改了数据库的投票节点。我的结构似乎不合理。_Angular_Typescript_Firebase Realtime Database_Rxjs_Angularfire2 - Fatal编程技术网

Angular 在RxJS中使用Filter操作符 更新:我更改了数据库的投票节点。我的结构似乎不合理。

Angular 在RxJS中使用Filter操作符 更新:我更改了数据库的投票节点。我的结构似乎不合理。,angular,typescript,firebase-realtime-database,rxjs,angularfire2,Angular,Typescript,Firebase Realtime Database,Rxjs,Angularfire2,这是我的数据库结构: -threadsMeta -posts -postId -votes -threadId -postId -uid: "down" //or "up" 我认为,下面代码中的注释描述了预期行为和实际行为 getMyUpVotes(threadId: string, uid: string): Observable<any> { //Get

这是我的数据库结构:

-threadsMeta
    -posts
        -postId


-votes
    -threadId
        -postId
            -uid: "down" //or "up"
我认为,下面代码中的注释描述了预期行为和实际行为

getMyUpVotes(threadId: string, uid: string): Observable<any> {
    //Get all the postId's for this thread
    let myUpVotes = this.af.database.list(`threadsMeta/${threadId}/posts`)
    .map(posts => {
        //Put each postId into a Firebase query path along with the uid from the method's params
        posts.forEach(post => {
            this.af.database.object(`votes/${threadId}/${post.$key}/upVotes/${uid}`)
            //Emit only upvotes from this user on this post
            .filter(data => data.$value === true)
        })
    })
    myUpVotes.subscribe(data => console.log(data)) //Undefined
    return myUpVotes
}
getMyUpVoces(threadId:string,uid:string):可观察{
//获取此线程的所有postId
让myupvows=this.af.database.list(`threadsMeta/${threadId}/posts`)
.map(posts=>{
//将每个postId与方法参数中的uid一起放入Firebase查询路径
posts.forEach(post=>{
此.af.database.object(`voces/${threadId}/${post.$key}/upvoces/${uid}`)
//在此帖子上仅从该用户发出UpVote
.filter(数据=>data.$value==true)
})
})
myupvows.subscribe(数据=>console.log(数据))//未定义
归还我的选票
}
我想您需要:

let myUpVotes = this.af.database.list(`threadsMeta/${threadId}/posts`)
    .flatMap(posts => 
          Observable.from(posts)
              .flatMap(post=>this.af.database.object(
                   `votes/${threadId}/${post.$key}/upVotes/${uid}`));
myUpVotes = myUpVotes.flatMap(t=>t.filter(x=>x.uid === true));

以下方法将为给定用户返回具有给定线程+的upvote+的POST数组:

getMyUpVoces(threadId:string,uid:string):可观察{
返回此.af.database.list(`threadsMeta/${threadId}/posts`)。获取(1)
//展平立柱阵列以单独发射每个立柱。
.mergeMap(val=>val)
//获取当前帖子上当前用户的投票。
.mergeMap(post=>
this.af.database.object(`voces/${threadId}/${post.$key}/upvoces/${uid}`)。take(1)
//只保留实际投票
.filter(upvote=>upvote.$value===true)
//将upvote转换为post,因为这是要发出的最终值。
.map(upvote=>post)
)
//在一个数组中收集所有帖子。
.toArray();
}
我已经添加了
.take(1)
,以强制Firebase Observable完成,这样就可以使用
toArray()
收集最终结果。这也意味着,一旦你获得了上升票,你就不再关注未来的价值变化。如果这是个问题,请告诉我

重要。您应该订阅方法外部的可观察内容

我创建了一个可运行的版本来说明(请注意,我使用的是普通的观测值,因为在这个环境中,角度和火基都不可用):

const getPostsForThread=(threadId)=>{
返回Rx.observative.of([
{key:'jcormtp',title:'Some post',threadId:threadId},
{key:'qapod',title:'other post',threadId:threadId},
{key:'bvxspo',title:'又一篇文章',threadId:threadId}
]);
}
常量getupvotesperposteruser=(postId,uid)=>{
返回Rx.observed.from([
{postId:'jcormtp',uid:'bar',value:true},
{postId:'qapod',uid:'bar',value:false},
{postId:'bvxspo',uid:'bar',value:true}
]).filter(uv=>uv.postId==postId&&uv.uid==uid);
}
const getMyUpVoces=(threadId:string,uid:string):Rx.Observable=>{
返回getPostsForThread(线程ID)
//展平立柱阵列以单独发射每个立柱。
.mergeMap(val=>val)
//获取当前帖子上当前用户的投票。
.mergeMap(post=>
getupvotesperposteruser(post.key,uid)
//只保留实际投票
.filter(upvote=>upvote.value==true)
//将upvote转换为post,因为这是要发出的最终值
.map(upvote=>post)
)
//在一个数组中收集所有帖子
.toArray();
}
//注意。方法之外的subscribe()
GetMyUpVoces('foo','bar')
.subscribe(val=>console.log(val))

所以我确实想出了一个非常适合我特殊情况的解决方案。我只是对可观测事物了解不够,不知道这是否是最好的方法。不管怎样,我最终将这个查询与我的posts查询“连接起来”。这对于我的特殊情况非常有效,因为我使用
ngFor
呈现帖子。我可以通过以下方式检查当前用户是否对特定帖子进行了上/下投票:

<i [class.voted]="post.vote === 'down'" class="fa fa-caret-down" aria-hidden="true"></i>

以下是我获取数据的方式:

getPosts(threadId: string, uid: string): Observable<any> {
    let result = this.af.database.list(`/threads/${threadId}/posts`)
    .switchMap(posts => {
        let joinedObservables: any[] = [];
        posts.forEach(post => {
            joinedObservables.push(this.af.database
                .object(`votes/${threadId}/${post.$key}/${uid}`)
                .do(value => {
                    post.vote = value.$value
                })
            )
        })
        return Observable.combineLatest(joinedObservables, () => posts);

    });
    return result
}
getPosts(threadId:string,uid:string):可观察{
让result=this.af.database.list(`/threads/${threadId}/posts`)
.switchMap(posts=>{
让JoinedObservable:any[]=[];
posts.forEach(post=>{
joinedObservables.push(this.af.database
.object(`vots/${threadId}/${post.$key}/${uid}`)
.do(值=>{
post.vote=value.$value
})
)
})
返回可观察的。组合相关测试(JoinedObservable,()=>posts);
});
返回结果
}
在这个实现中,我不断从投票中获取排放量,这一点很重要,因为用户投票必须反映在页面上,不仅是在加载时,而且是在他们更改投票时


我想知道是否有人预见到这方面的任何问题。我对这项技术一点也不在行,我想知道我是否遗漏了什么。在选择此作为答案之前,我会给其他回答过的人机会表达任何反对意见并编辑他们自己的答案。

嘿,谢谢你的回答。我对第一次观测到的发射项目不感兴趣,只是想把
post
的键插入我的Firebase路径。我不希望这些键出现在结果的可观察状态中。对,我想这会让你明白你在追求什么。我得到错误“this.af.database.list(…).flatMap不是函数”。看来flatMap无法以这种方式在Firebase参考上运行。可能。。。你试过了吗。导入'rxjs/add/operator/flatMap';我有。这不是唯一的问题。Sublime还抱怨
Rx.Observable
——特别是
Rx
关键字。如果我删除它,升华就不会识别帖子上的$key属性。嘿,谢谢你的回答。结果对象/阵列是可观察的,这一点很重要。原因是,像reddit或s.o.一样,向上投票/向下投票,但