Решение 1: Предполагая, что у вас есть доступ к long и lat, когда вы перемещаете эти объекты в базу FireBase
Когда вы нажимаете boulangerie
в Firebase, добавляете вычисленное расстояние до объектапрежде чем отправить его в базу данных.Это более эффективно, чем делать это для каждого объекта, когда вы получаете коллекцию boulangeries
.
Когда вы запрашиваете коллекцию boulangeries
, используйте orderBy('distance')
при обращении к базе данных (при условии, что ваша база данных firebaseЗависимость называется db
):
Если при использовании базы данных реального времени метод в вашем BoulangerieService
будет выглядеть так:
getAll(): Observable<Boulangerie[]> {
db.collection('items', ref => ref.orderBy('distance')).valueChanges();
}
В Firestore это будет выглядеть так:
getAll(): Observable<Boulangerie[]> {
this.db.list('/boulangeries', ref => ref.orderByChild('distance')).valueChanges()
}
Тогда, если вам нужно отсортировать по алфавиту или по любому другому свойству, вы можете адаптировать один из каналов, представленных в других ответах, чтобы сделать это довольно красиво:)
Решение2: Если у вас нет доступа к long и lat при нажатии на firebase
Я настоятельно рекомендую вам делать следующее в сервисе, а не в компоненте - это лучше, потому что выотделяют манипулирование данными от представления их в компоненте.Это также лучший способ сделать это с помощью RxJS.Обратите внимание, что вам нужно будет импортировать оператор map
из RxJS, чтобы сделать следующее:
Убедитесь, что доступны долгота и широта и ваша функция distanceTo()
в службе или компоненте, где вы выполняетепозвоните в firebase и попробуйте:
// If using firestore:
getAll(): Observable<Boulangerie[]> {
this.db.list('/boulangeries', ref => ref.orderByChild('distance')).valueChanges()
.pipe(
map((boulangeries: Boulangerie[]) => {
boulanderies.forEach((boulangerie) => {
boulangerie.distance = distanceTo(boulangerie.coordX, boulangerie.coordY, latitude, longitude)
})
})
)
}