【问题标题】:How can I add a condition to my Firebase query in Ionic?如何在 Ionic 中向 Firebase 查询添加条件?
【发布时间】: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 &copy; <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


    【解决方案1】:

    我建议您在“Drop”模型中添加一个可选的布尔参数来表示一个 kingdrop。 由于您的国王掉落很少,因此您应该遍历每个项目并使用 indexof 方法搜索原始数组以查找匹配项 然后,您应该将该数组索引处的 drop 的可选参数更改为 true,然后使用此变量加载您的图标 示例:

    【讨论】:

      猜你喜欢
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多