首页 > 解决方案 > 无法从 Angular 中的 Firebase 获取对象的密钥

问题描述

在学习 Angular 时,我一直在尝试创建一个简单的应用程序。该应用程序很简单,在主页上获取员工列表并通过单击员工查看他们的详细信息。

该项目有 2 个组件和 1 个服务:TableViewComponentViewProfileComponentDataService。通过首页路由,默认显示 TableViewComponent。单击员工时,浏览器会导航到“example.com/view/:id”和 ViewProfileComponent。

所以这就是问题所在。当浏览器位于“主页”时,DataService 可以完美运行。一旦 URL 切换到 '/view/:id',DataService 函数“ private _findEmployeeById() ”返回undefined,而不是我需要的对象的键。再次,它可以在主页上运行!

我已经为此苦苦挣扎了几天,无法使其正常工作。我看过Angular Tour of Heroes,在我看来,几乎是一样的,所以这就是我找不到问题的原因。

这是Github上完整项目的链接,也许它会更容易理解问题。

private _findEmployeeById(id: number): string {
    const ref = this.db.database.ref();
    let key: string;

    // Key returns undefined, when the URL is example.com/view/id
    // Works properly on home page (when the URL is example.com)
    ref.child('employee').orderByChild('id').equalTo(id).once('value', snap => {
      snap.forEach(data => {
        key = data.key;
      });
    });

    return key;
}

有任何想法吗?

标签: angularfirebasefirebase-realtime-database

解决方案


这是你的罪魁祸首:

ref.child('employee').orderByChild('id').equalTo(id).once('value', snap => {
    snap.forEach(data => {
    key = data.key;
    });
});

这段代码是异步的,这意味着它不会立即得到处理。事实上,它会启动请求,然后愉快地继续它可以处理的下一件事情,在你的情况下是return key. 当它到达return key实际确定 key 值的部分时,尚未处理,因此您得到未定义。

我想你可能想重构你的方法看起来像这样:

private _findEmployeeById(id: number): Promise<string> {
  const ref = this.db.database.ref();
  let key: string;

  return ref.child('employee').orderByChild('id').equalTo(id).once('value').then(snap => {
    snap.forEach(data => {
      key = data.key;
    })
    return key;
  })
}

这就是说,返回承诺返回值的函数,然后在解析时返回该值。您会注意到我将函数签名更新为最终解析为字符串的承诺。这将对您方法的任何使用者产生级联影响。

代替:

const key = this._findEmployeeById(removeEmployee.id);

你需要做

this._findEmployeeById(removeEmployee.id).then(key => {
   console.log(key);
})

我还要补充一点,我从来没有对 firebase 做过任何事情,所以可能有更好的 firebasey 方式来处理这个问题,但这是你问题的症结所在。如果您不熟悉事件循环,值得一看: https ://www.youtube.com/watch?v=8aGhZQkoFbQ


推荐阅读