【发布时间】:2019-10-07 14:42:48
【问题描述】:
我正在开发一个基于位置的应用程序,作为大学项目的一部分,用户应该能够“将某些消息放在 hin 周围以供其他用户查看。我使用 Ionic v4 和 Firebase 作为我的数据库。不幸的是,我对 Ionic 和 Firebase 还很陌生,所以如果我在这里找不到问题的答案,我真的不知道该怎么办,所以我想我还是问问吧。
更多背景知识:我得到了用户可以编写的上述 drops,现在我希望其他用户能够对这些 drops 投赞成票和反对票。 drops 在带有leaflet 的openstreetmap 中可见。到目前为止,我的一切都按预期工作,但现在我想根据那里的分数获得所有 drop 的前 20% 并更改我地图上显示的图标。我想我可以通过在我原来的查询中添加另一个数据库查询来实现这个购买,这只是从我的数据库中获取每个 drop。我正在使用ionic service 提取数据库条目。
这是我获取每个条目的原始查询:
private dropsCollection: AngularFirestoreCollection<Drop>;
private drops: Observable<Drop[]>;
this.dropsCollection = db.collection('drops', ref =>
ref.where('createdAt', '>=', validMinTime)
);
这是获取 kingDrops 的查询:
private kingdropsCollection: AngularFirestoreCollection<Drop>;
private kingDrops: Observable<Drop[]>;
// 2 should be replaced dynamicly with the total amount of drops*0.2
const topDrops = 2;
this.kingdropsCollection = db.collection('drops', ref =>
ref.orderBy('score', 'desc').limit(topDrops)
);
据我所知,语法应该没问题,但是如何在前端中将此查询实现为“条件”?我需要能够动态地确定我的 drops 中的哪一个是 kingDrop 并相应地更改图标。这是我的 home.page.ts
的代码import {Component, ElementRef, ViewChild} from '@angular/core';
import * as Geolib from 'geolib';
import leaflet from 'leaflet';
import {NavController} from '@ionic/angular';
import {Drop, DropService} from '../../services/drop.service';
import {AppComponent} from '../../app.component';
import {Router} from '@angular/router';
import {UserService} from '../../services/user.service';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss']
})
export class HomePage {
myDrops: Drop[];
@ViewChild('map') mapContainer: ElementRef;
map: any;
constructor(
private router: Router,
public navCtrl: NavController,
public dropService: DropService,
public appComponent: AppComponent,
public userService: UserService
) {}
ionViewDidEnter() {
this.loadmap();
}
loadmap() {
const positionIcon = leaflet.icon({
iconUrl: '../../../assets/icon/position.png',
shadowUrl: '../../../assets/icon/position-shadow.svg',
iconSize: [30, 30], // size of the icon
shadowSize: [30, 30], // size of the shadow
iconAnchor: [0, 0], // point of the icon which will correspond to marker's location
shadowAnchor: [2, -2], // the same for the shadow
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
this.map = leaflet.map('map').fitWorld();
leaflet.tileLayer(
'https://api.maptiler.com/maps/positron/{z}/{x}/{y}.png?key=JrASdfPCkNw3CYBKAD6E',
{
attributions:
'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18,
minZoom: 15
}
)
.addTo(this.map);
this.map.locate({
setView: true,
maxZoom: 10,
minZoom: 15
})
.on('locationfound', e => {
const markerGroup = leaflet.featureGroup();
const marker: any = leaflet
.marker([e.latitude, e.longitude], {
icon: positionIcon,
zIndexOffset: -1000 // put the markers on top of the location marker
})
.on('click', () => {
console.log('Position marker clicked');
});
markerGroup.addLayer(marker);
this.map.addLayer(markerGroup);
})
.on('locationerror', err => {
console.log(err.message);
});
this.loadMarkers();
}
loadMarkers() {
const greyDropIcon = leaflet.icon({
iconUrl: '../../../assets/icon/grey-drop.png',
shadowUrl: '../../../assets/icon/drop-shadow.svg',
iconSize: [25, 30], // size of the icon
shadowSize: [25, 30], // size of the shadow
iconAnchor: [0, 0], // point of the icon which will correspond to marker's location
shadowAnchor: [2, -2], // the same for the shadow
popupAnchor: [-3, -5] // point from which the popup should open relative to the iconAnchor
});
this.dropService.getDrops().subscribe((drops: any) => {
drops.forEach(singledrop => {
if (this.dropService.isDropVisible(singledrop)) {
const dropGroup = leaflet.featureGroup();
// check visibleDrops array of user for drops and add them
const dist = this.checkDropDistance(singledrop);
if (dist < 1500 && singledrop.score > -10) {
this.setDropVisible(singledrop);
} else if (singledrop.score > -10) {
const drop: any = leaflet.marker([singledrop.latitude, singledrop.longitude], {
icon: greyDropIcon
})
.on('click', () => {
console.log('Marker clicked, but out of range');
});
dropGroup.addLayer(drop);
this.map.addLayer(dropGroup);
}
}
});
});
}
// ...
}
我尝试像上面的 drops 一样实现 kingDrops,如下所示:
this.dropService.getKingDrops().subscribe((drops: any) => {
//..
});
但它没有成功,而且它会被复制,因为原来的水滴已经在我的地图上。我需要某种条件来确定 drop 是否是 kingDrop 与否并相应地实现图标,但我不知道编写这样一个条件的语法..
有人可以帮我吗?
【问题讨论】:
标签: angular typescript firebase ionic-framework google-cloud-firestore