angular 5 和 firebase/angularfire,使用密钥检查密钥是否存在于另一个 table

angular 5 and firebase/angularfire, using keys to check if key is present in another table

我的数据库中有一个情况(附有屏幕截图),用户可以拥有 1 门或多门课程,我使用他们的密钥作为 table 中的密钥,如下所示。

如您所见,以 Dpof2 结尾的密钥在两个 table 中并且可以访问启动板。

现在我已经编写了一些代码,使用 'launchpad' 或 'independence'.[=17= 的引用创建了 /courses table 中所有键的数组]

这个 return 数组很好,但是从这里我 运行 在进行比较和获取与数组中的键匹配的用户时遇到了问题。

这是我在 .ts 文件中的代码

getCourses(course) {

this.courses = this.getCourseKeys(course);

if (this.courses.length > 0) {
  let test = [];

  let users = this.adminService.getUsers();
  let usersLength = 0;
  users.subscribe(snapshots => {
    usersLength = snapshots.length;
    console.log(usersLength);
    snapshots.forEach(snapshot => {
      for (let i = 0; i < usersLength; i++) {
        for (let j = 0; j < this.courseKeys.length; j++) {
          if (this.courses[j] === snapshot.$key[i]) {
            test.push(snapshot);
          }
        }
      }
    });
    console.log('user data');
    console.log(test)
  });
}
}

private getCourseKeys(course): Promise<any> {
this.courseKeys = [];
this.courses = this.adminService.getUsersCourses(course).subscribe(snapshots =>
  snapshots.forEach(snapshot => {
    this.courseKeys.push(snapshot.$key);
    console.log(this.courseKeys)
  })
);
return new Promise<any>(resolve => {
  return this.courseKeys;
});
}

这是服务中的 getUsers 函数,但我不知道它是否重要。

public getUsers(): FirebaseListObservable<any[]> {
this.userId = this.auth.currentUserId;
return this.auth.currentUserDetails(this.userId).switchMap(snapshot => {
  this.foyer = snapshot.foyer;
  this.access = snapshot.access;
  if (this.access !== 'superadmin') {
    return this.db.list('/users', {
      query: {
        orderByChild: 'foyer',
        equalTo: this.foyer
      }
    });
  } else {
    return this.db.list('/users');
  }
}) as FirebaseListObservable<any[]>;
}

我尝试了多种方法,但现在一直在尝试让 getCourses() 函数等待 getCourseKeys 完成。目前它 return 是一个错误,指出 return 来自 getCourseKeys 是非法的。我的 firebase/angular2 知识有限,如有任何帮助,我们将不胜感激。

好吧,angularfire2 的神奇之处在于它允许您使用超级方便的 Observables 和 rxjs 运算符的强大功能,而不是 Firebase SDK for web 提供的经典的基于 promiss 的 API。 Angular 使用 Observables 效果非常好,所以我鼓励你使用 Observables 来做。另外,顺便说一句,您应该将 angularfire2 更新到最新版本,这就是我向您展示的方式。如果你愿意,还有另一个关于数据关系的类似问题 我也已经回答了。

所以让我假设您已经使用如下接口对数据建模:

interface User {
    uid: string;
    name: string;
    // Or whatever
}

interface Course {
    identifier: string; //  Like launchpad, independence
    // Or whatever
} 

现在请注意可以放入服务中的辅助方法:

getCourse(identifier: string): Observable<Course[]> {
    return this.db
    .object<Course>(`/coursesListSomewhere/${identifier}`)
    .valueChanges();
}

// And this method is the crucial one which
// will give the exact array of Course objects
// That this user has been subscribed to,
// So you can do whatever you want with them,
getCourseListForUser(uid: string): Observable<Course> {
    return this.db
    .list(`/courses/${uid}`)
    .snapshotChanges() // This emmits an array of snapshots
    .map(snapshots => {
        return snapshots.map(snapshot => snapshot.key)
    }) // Here we map each snapshot to the key, so we get an array
    // of course identifiers, which we'll switchmap to the actual courses
    .switchMap((coursesIdentifierArray: string[]) => {
        // Some rxjs and array transformation so the final Observable
        // will emmit the Course[] array for this particular user
        return Observable.combineLatest(
            coursesIdentifierArray.map(this.getCourse)
        ).map(Array.prototype.concat);
    })
}

否,如果在某些组件中你想为某些输入的 userUid 字符串设置课程数组,你可以像这样获得可观察的课程:

@Input() userUid: string;

courses$: Observable<Course[]>;

constructor(someService: SomeService) {
    this.courses$ = this.someService.getCourseListForUser(this.userUid);
}

然后用你想要的任何方式用异步管道轻松解包到你的模板中:

<div *ngFor="let course in courses$ | async">
  {{ course | json }}
</div>

希望这对您有所帮助,祝您应用顺利!