2017-02-10 5 views
1

Я довольно новичок в Angular and Firebase, так что извините, если вопрос тривиален.Как отображать информацию о связанных объектах с одного объекта в angularfire2

Я хотел бы знать, как отображать информацию о связанных объектах с одного объекта в angularfire2?

В принципе, я хочу отображать имена ролей, назначенные пользователю.

Вот что я имею в базе данных Firebase.

role : { 
    roleKey1 : { 
    name : Designer 
    ... 
    }, 
    roleKey2 : { 
    name : Manager 
    ... 
    } 
}, 
user: { 
    userKey1 : { 
    name : Bill, 
    roles : { 
     roleKey1: true, 
     roleKey2: true, 
    }, 
    ... 
    }, 
    userKey2 : { 
    name : Steve, 
    roles : { 
     roleKey1: true, 
    }, 
    ... 
    }, 
} 

В мой контроллер у меня есть следующие:

export class UserComponent implements OnInit { 
    public user: Observable<any>; 
    public id: string; 

    constructor(private af: AngularFire, private activatedRoute: ActivatedRoute) { 
    } 

    public ngOnInit() { 

     const id = this.activatedRoute.params.subscribe(params => { 
     if (params['id']) { 
     this.id = params['id']; 
     console.log(params['id']); 
     } 
    }); 

    this.user = this.af.database.object('/user/' + this.id) 
    .switchMap((user) => { 
     const roleKeys = Object.keys(user.roles); 
     return Observable.forkJoin(
     roleKeys.map((roleKey) => this.af.database.object('/role/' + roleKey) 
     .first() 
     ), 
     (...roles) => { 
      roleKeys.forEach((roleKey, index) => { 
      user.roles[roleKey] = roles[index]; 
      }); 
      return user; 
     } 
    ); 
    }); 
    } 

В моем шаблоне я следующее:

<h2>Name: {{ (user | async)?.name }} roles</h2> 

<ul *ngFor="let role of user.roles | async"> 
    <li>{{ role.name }}</li> 
</ul> 

Текущий результат: отображается только имя пользователя. не Ничто для роли

Ожидаемые результаты:

  1. с URL: https://.../user/userKey1

    • Билл ролях:
      • Менеджер
      • Дизайнер
  2. с URL: https://.../user/userKey2

    • Стив роли:
      • Дизайнер

Спасибо за вашу помощь!

+0

что выход 'console.log (пользователь)' – sugarme

+0

Привет @sugarme. Вывод console.log (this.user) - это FirebaseObjectObservable {_isScalar: false, $ ref: U, source: FirebaseObjectObservable, operator: SwitchMapOperator} – Marco

+0

, пожалуйста, посмотрите мое решение в ответе. Еще немного дольше. Интерфейсы, созданные для адаптации структуры данных и шаблона html. Сообщите мне, есть ли какие-либо ошибки из консольного представления. – sugarme

ответ

0

Вот мое решение (не проверено):

import { Component, OnInit } from '@angular/core'; 
    import { ActivatedRoute } from '@angular/router'; 
    import { Observable } from "rxjs/Observable"; 
    import { AngularFire } from 'angularfire2'; 


    interface Role { 
     roleKey: string; 
     name: string; 
    } 

    interface User { 
     name: string; 
     roles: Array<boolean>; 
    } 

    interface Profile { 
     name: string; 
     roles: Array<Role> 
    } 

    export class UserComponent implements OnInit { 
    public user: Observable<any>; 
    public id: string; 

    constructor(private af: AngularFire, private activatedRoute: ActivatedRoute) { 
    } 

    ngOnInit() { 

     const id = this.activatedRoute.params.subscribe(params => { 
     if (params['id']) { 
      this.id = params['id']; 
      console.log(params['id']); 
      this.getProfile(this.id).then(profile =>{ 
       console.log(profile); // <--- Is it what you want? 
       this.user = Observable.of(profile); 
      }).catch(error => { console.log(error); }) ; 

     } 
     }); 
    } 

     getProfile(userKey: string): Promise<Profile> { 
      return new Promise(resolve =>{ 
       var profile: Profile; 
       this.af.database.object('/user/' + userKey).subscribe(resUser =>{ 
        if(resUser) { 
         var tempUser: User = resUser; 
         var roleKeys = []; 

         profile.name = tempUser.name; 

         roleKeys = tempUser.roles.filter(key =>{ 
          return (key == true); 
         }); 
         if(roleKeys.length > 0) { 
          var tempRoles = []; 
          var count = roleKeys.length; 
          roleKeys.forEach(roleKey =>{ 
           count = count - 1; 
           this.af.database.object('/role' + roleKey).subscribe(resRole =>{ 
            if(resRole) { 
             tempRoles.push({roleKey: resRole.name}); 
             if(count == 0) { 
              profile.roles = tempRoles; 
              resolve(profile); 
             } 
            } 
           }, (error) =>{ console.log(error); }); 
          }); 
         } else { 
          // No roles found. Display name only 
          profile.roles = []; 
          resolve(profile); 
         } 

        } 
       }, (error) => { console.log(error); }); 
      })  
     } 

    } 
0

Спасибо @sugarme, Ваш ответ мне очень помог. Наконец-то я нашел решение.

export class UserComponent implements OnInit { 

    public user: Observable<any>; 
    public id: string; 

    constructor(private af: AngularFire, private activatedRoute: ActivatedRoute) { 
    } 

    public ngOnInit() { 

    this.id = this.activatedRoute.params.subscribe(params => { 
     if (params['id']) { 
     this.id = params['id']; 
     console.log(params['id']); 
     } 
    }); 

    this.user = this.af.database.object('/user/' + this.id) 
    .map(_user => { 
     const tempRoleKeys = []; 
     const tempRoleObjects = []; 
     if (_user.roles) { 
     Object.keys(_user.roles) 
     .forEach((roleKey, index) => { 
      tempRoleKeys.push(roleKey); 
      tempRoleObjects.push(this.af.database.object('/role/' + roleKey)); 
     }); 
     _user.roleKeys = tempRoleKeys; 
     _user.roleObjects = tempRoleObjects; 
     } 
     return _user; 
    }); 
    } 

И для шаблона