我正在制作具有地理位置的离子应用程序,地理定位由处理所有Havershine公式(地理位置)计算的Firebase Geofire库处理。
我已经修改了以下内容来处理typescript(http://jsfiddle.net/katowulf/9GEFf/),基本上它合并了2个firebase表/集合(超过2个已加入,但为了简洁而将它们留下)我想要的结果是将这些表格提供给我的主页组件,显示附近的所有用户。
我理解Angular的大多数概念但是承认我很难成功地执行Observables和RxJS,或者我尝试在数组中复制数据,或者当一个值得到更新时它在视图中复制等,否则它根本就不会工作 - 我已经多次遇到这些场景,所以我认为这可以帮助很多人,如果一个职业角色的人可以对此有所了解..
我的第一个函数listusers获取当前活动用户lattitude / long并将其提供给geoFire查询,该查询迭代数据库,收集半径20英里范围内的任何其他格子/长度。
然后将这些用户ID一次一个地提供给loadUser函数,该函数指定要连接的表等,然后执行joinPaths函数,这是数据收集和对象合并魔术发生的地方......
然后将数据输出到this.show(mergedObject),这是我希望能够从模板中获取数据的地方,但我不确定如何做到这一点,我已经尝试了Observable.of, Observable.from etc但数据没有显示在我的模板中,或者像我之前提到的那样复制了数据......
任何天才都有关于如何完美运作的任何想法?它确实是让我回到应用程序的一件事。
我认为,因为这会迭代附近的每个用户,这可能会导致observables的问题 - 我需要的是收集所有结果的东西,当它完成时创建一个可以馈送到我的home组件的数组,我很高兴在这个阶段没有实时更新这个列表,从用户体验的角度来看,它可能更好,让用户可以随意更新。
//我的服务组件
public joinPaths(id, paths, callback) {
let returnCount = 0;
let expectedCount = paths.length;
let mergedObject = {};
paths.forEach( (p) => {
this.fb().database().ref(p).child(id).once('value',
// success
(snap) => {
this.extendObj(mergedObject, snap.val());
if (++returnCount === expectedCount) {
this.show(mergedObject);
}
},
(error) => {
returnCount = expectedCount + 1; // abort counters
console.log( "error in joinPaths ", error );
}
);
});
}
public loadUser(userId) {
this.joinPaths(userId, ['users', 'geofire'], this.show);
}
public show(obj?): Observable<any> {
return Observable.of( obj );
}
public listUsers() {
this.fb().database().ref(`/users/${this.userID}/lastKnownLocation`).once('value').then( (snapshot) => {
this.geoFire.query({ center: [snapshot.val().lat, snapshot.val().lng], radius: 20 }).on( "key_entered", (key, location, distance) => {
this.loadUser(key);
});
});
}
// merge the tables data into one object
private extendObj<T1,T2>(objA: T1, objB: T2) {
for(let key in objB){
if(objB.hasOwnProperty(key)){
(objA as any)[key] = (objB as any)[key];
}
}
return <T1&T2>objA;
}
// my home.ts
import { Component, NgZone } from '@angular/core';
import { NavController, PopoverController } from 'ionic-angular';
import { geoApi } from '../../providers/geo';
import { Observable } from 'rxjs/Observable';
import { Storage } from '@ionic/storage';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public users$: Observable<any>;
constructor( public _api: geoApi ) {
this._api.listUsers();
this.users$ = this._api.show();
}
}
// home.html
<ion-header>
<ion-navbar>
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-grid>
<ion-col *ngFor="let c of users$" class="member-item" tappable width-33>
<ul class="o-list-reset c--user">
<li class="c-username o-center c-uname">{{ c?.firstName }}</li>
</ul>
</ion-col>
</ion-grid>
</ion-content>
并且在这些函数的每次迭代中,将类似于以下内容的用户数据馈送到最终函数show()
{
// geofire table/collection data merged
"g": "u2fkbvz3rk",
"l": [
51.085535799999995,
13.457294699999998
],
// users table/collection data merged
"profile": {
"about": {
"avatarUrl": "assets/img/generic.png",
"birthday": "2015-01-01",
"blockedBy": "",
"email": "janek@gmail.com",
"firstName": "Janek",
"gender": "female",
"id": "yrdUxr1dlmOyPJ6kcD2ss55gfd4",
"isDeleted": 0,
"isFacebookLinked": "",
"isVerified": 0,
"lastKnownLocation": {
"lat": 51.085535799999995,
"lng": 13.457294699999998
},
},
}