如何在angularfire2中显示来自一个对象的相关对象信息

时间:2017-02-10 12:08:56

标签: angular typescript firebase-realtime-database angularfire2

我对Angular和Firebase很新,所以如果这个问题很简单,我很抱歉。

我想知道如何在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. 使用网址:https://.../user/userKey1

    • 比尔角色:
      • 管理器
      • 设计
  2. 使用网址:https://.../user/userKey2

    • 史蒂夫角色:
      • 设计
  3. 感谢您的帮助!

2 个答案:

答案 0 :(得分: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); });
            })    
        }

    }

答案 1 :(得分: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;
    });
  }

对于模板

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

<ul *ngFor="let roleObject of (user | async)?.roleObjects">
    <li><a [routerLink]="['/role/'+(roleObject | async)?.$key]">{{ (roleObject | async)?.name }}</a></li>
</ul>