Как динамически связать, где условия в firebase, не зная заранее, сколько условий будет установлено - PullRequest
0 голосов
/ 12 апреля 2019

Я работаю в Angular с firebase.

Я хочу создать функцию, которая получит два аргумента string и object и возвращает Observable отфильтрованных данных в соответствии с парами ключ-значение объекта из конкретной коллекции динамически.

Например, когда я назову это так, я ожидаю такой результат:

dynamicFilter('users',{name: 'Jack', age: 30})

Он должен оценить этот вызов:

firebase.collection('users',ref => ref.where('name','==','Jack').where('age','==',30))

Таким образом, я могу подписаться на него следующим образом:

dynamicFilter('users',{name: 'Jack', age:30}).subscribe(res => {
    console.log(res)
})

Я хочу, чтобы функция была универсальной, поскольку я заранее не знаю, сколько условий будет передано через объект.

Iпопробовал это:

constructor(private db: AngularFirestore){}

dynamicFilter(collectionName: string, options: object){

    let targetCollection = this.db.firestore.collection(collectionName)
    let query;
    let keys = Object.keys(options)

    for(let i = 0; i < keys.length; i++ ){
        if(i === 0){
            query = targetCollection.where(keys[i],'==',options[keys[i]])
        }else{
            query = query.where(keys[i],'==',options[keys[i]])
        }
    }
    return query
}

Так что можно сделать с этим возвращенным значением?Это экземпляр класса Query, и я думаю, я могу вызвать метод get, который возвращает обещание, например query.get().then(res => console.log(res)).Но res - это еще один экземпляр класса QuerySnapshot.Как я могу просто получить данные?

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

Я искал все ресурсы, которые вы можете себе представить, и, наконец, избавился от этого и начал экспериментировать самостоятельно, и все готово, он работает просто отлично, вы бы даже не подписались на него, он запускается черезCallback function.

Usecase:

1.Вы напишите приведенный ниже код в сервисе, чтобы сохранить ясность и возможность повторного использования.

Например, давайте назовем его DataService:

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})

export class DataService {

constructor(private fire: AngularFirestore) { }

dynamicQueryFilter(collectionName: string, options: object, callbackFn: Function): void{

    const bindedCallback: Function = callbackFn.bind(this)

    const targetCollection = this.fire.collection(collectionName).ref
    const optionPairs = Object.entries(options)

    let queryMap = targetCollection.where(optionPairs[0][0],'==',optionPairs[0][1])

    optionPairs.slice(1).forEach(item => {
       queryMap = queryMap.where(item[0],'==',item[1])
    })

    queryMap.get()
      .then(resolve => {
        const documents = []
        resolve.forEach(doc => documents.push(doc.data()))
        bindedCallback(documents)
      })
}

2. Затем внедрите его в свой компонент

export class AppComponent implements OnInit {

    constructor(private db: DataService){}

    users: User[];

    ngOnInit(){
        this.db.dynamicQueryFilter
           (
            'users',
            {name: 'Jack', age: 30, profession: 'Programmer', isMaried: true},
            (res) => this.product = res
           )
    }

}

3. Отнесите всех женатых программистов по имени Джек, которым 30 лет в вашем шаблоне

<div *ngIf="users">
    <div *ngFor="let user of users">
        <h2>{{user.name}} {{user.surname}}</h2>
        <hr>
        <h4>Additional Info</h4>
        <div><b>Age: </b>{{user.age}}</div>
        <div><b>Profession: </b>{{user.profession}}</div>
        <div><b>Adress: </b>{{user.adress}}</div>
        <div><b>Phone: </b>{{user.phone}}</div>
        //and so on....
    </div>
</div>

С помощью этого инструмента вы можете выполнять любую фильтрацию, которую вы можете представить ДИНАМИЧЕСКИ.

Вы можете привязать аргументы dynamicQueryFilter к входным данным или любым формам в вашем шаблоне, и позволить пользователю выполнять интерактивное мульти-отображение в реальном времени.фильтрация.

Отдельное спасибо Фрэнку ван Пуффелену за то, что он поделился своими знаниями.

0 голосов
/ 12 апреля 2019

Чтобы получить данные от QuerySnapshot:

querySnapshot.forEach(function(doc) {
  console.log(doc.data());
});

Итак:

dynamicFilter('users',{name: 'Jack', age:30}).subscribe(querySnapshot => {
    querySnapshot.forEach(function(doc) {
      console.log(doc.data());
    });
})

Подробнее об этом см.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...