AngularFire2-присоединение участников и пользователей

Я пытаюсь перечислить разговоры пользователей в приложении AngularFire2, структура которого следующая:

болтает

"chat1": {
  title: "First chat",
  lastMessage: "Hello world",
  members: {
    "user1": true,
    "user2": true,
  }
}

пользователи

"user1": {
  name: "Ben",
  surname: "Bennsay"
}
"user2": {...}

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

Вопрос 1: Этот пример немного отличается от тогдашней официальной рекомендации, но я чувствую, что он все равно будет действительным и масштабируемым. Я прав ?

Вопрос 2: как на самом деле присоединиться к участникам и пользователям, чтобы иметь usersмассив в моем списке чатов ?

Вот что у меня пока есть.

// retrieve chats "user1" participates in
this.afChatsRef = this.af.database.list(this.datastore(), {
  query: {
    orderByChild: "/members/user1", // by user id in members
    equalTo: true,
  }
}).map(chats => {
   chats.map(chat => {
        // HMMM? WHAT TO DO HERE ?
   });
   return chats;
});

Спасибо заранее.

Обновление я также попытался следующее, что кажется не совсем правильным (и я не могу получить доступ к свойствам пользователя).

 this.af.database.list(this.datastore()).map(chats => {

            chats.map(chat => {
                // chat.users = [];

                for (var key in chat.members) {
                    this.af.database.object("/users/" + key).subscribe(user => {
                        chat.members[key] = user;
                    });
                }

                return chat;
            });

            console.log(chats);
            return chats;
        });

1 ответ

  1. Вы хотите вернуть вложенную карту и получить пользователей внутри нее. Что-то вроде этого;

    // retrieve chats "user1" participates in
    this.afChatsRef = this.af.database.list(...).map(chats => {
       // Note the return!
       return chats.map(chat => {
            // Avoid side effects by storing members separate from the keys
            chat.memberData = {};
            // Iterate keys and download members
            Object.keys(chat.members||{}).forEach(uid => {
                // `users` represents a service to cache and load users on demand
                chat.memberData[uid] = users.load(uid);
            });
       });
       return chats;
    });
    

    Вот хороший способ создать сервис пользователей с кэшированием:

    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs/Rx';
    import { AngularFireDatabase } from 'angularfire2/database';
    
    @Injectable()
    export class UserProvider {
      db: AngularFireDatabase;
      users: Map<String, Observable<User>>;
    
      constructor(db: AngularFireDatabase) {
        this.db = db;
        this.users = new Map();
      }
    
      load(userid:string) : Observable<User> {
        if( !this.users.has(userid) ) {
          this.users.set(userid, this.db.object(`members/${userid}`).valueChanges());
        }
        return this.users.get(userid);
      }
    }
    
    export interface User {
      name:string;
      nick:string;
    }
    

    А вот рабочий пример асинхронных соединений в AngularFire2.