【问题标题】:Calling arrays in Firebase using Angular 2使用 Angular 2 在 Firebase 中调用数组
【发布时间】:2017-02-05 21:47:27
【问题描述】:

我想知道如何使用 Angular 2 调用 Firebase 数组。在我的示例中,我的 Firebase 数据库中有一个数组 addnoteDo the dishes 有两个单独的迭代,我想将它们打印到我的 HTML 的无序列表中。

我的private addsnotes 中的[] 会引发错误,我并没有真正预料到其他情况。在不了解如何输出数组的情况下,我用它来说明我想要实现的目标。我还标记了正在拨打电话的相关区域。

我的rainbow.component.html

<div><ul>
    <li *ngFor="let addsnote of addsnotes">{{addsnote}}</li>
</ul></div>

我的 firebase 架构:

我的 rainbow.component.ts

export class Rainbow implements OnInit{
private addsnotes: [];
private username: string;

ngOnInit(){
    var self = this;
    var user = firebase.auth().currentUser;
    var getUserInfo = firebase.database().ref('users/' + user.uid); 
    setTimeout(acquisition, 1000);

    function acquisition(){
    if (user){
        getUserInfo.once('value', function(snapshot){
                self.username = snapshot.val().username;
                self.addsnotes = snapshot.val().addnote; //incorrect
            });     
        }
    }
}

}

【问题讨论】:

  • 有什么理由不使用AngularFire2?即使您不想使用该库,browse the code 也可能是一个好主意,因为它可以处理您要处理的情况等等。
  • 那么使用 AngularFire2,我的数组请求会类似于:export class Rainbow{ addsnotes: Observable addnote; constructor(af: AngularFire){this.addsnotes = af.list('/users')} }

标签: angularjs angular firebase firebase-realtime-database


【解决方案1】:

如果您希望 AngularFire2 可以轻松调整到 Observables 的强大功能,以便您可以检测到 Firebase 端的更改并自动更新您的用户注释。使用 AngularFire2,您的解决方案看起来更像这样......

rainbow.component.html

<div>
  <ul>
    <li *ngFor="let addsnote of addsnotes$ | async">{{ addsnote.$value }}</li>
  </ul>
</div>

rainbow.component.ts

import { Injectable } from '@angular/core';
import { AngularFire } from 'angularfire2';
import { Observable } from 'rxjs/Observable';

export class RainbowComponent implements OnInit {
  private addsnotes$: Observable<string[]>;
  private username$: Observable<string>;

  constructor (
    private af: AngularFire
  ) {}

  ngOnInit () {
    let user = firebase.auth().currentUser,
        userNamePath = `users/${user.uid}/username`,
        notesPath = `users/${user.uid}/addnote`;

    this.username$ = this.af.database.object(userNamePath);
    this.addsnotes$ = this.af.database.list(notesPath);
  }
}

在模板 HTML 中使用 Observables 时,您将需要 async 管道。它将自动订阅以提取数据。这段代码和之前的代码最大的不同在于,只要你的addsnotes 数据发生变化,它就会自动在 HTML 视图上显示变化。如果您想保持它像之前的代码一样使用once('value') 将其限制为一次调用,您可以在this.af.database.list(notesPath) 的末尾添加一个.take(1),以便只获取列表值一次。

此外,我建议在您的笔记中添加一个子字段,例如order,以便您可以按照您想要的顺序对您的列表进行排序。您可以找到有关如何使用 AngularFire2 here 进行排序的信息。

希望这会有所帮助。

【讨论】:

  • 我不知道为什么,但对于用户和添加注释的每次调用,我都会得到 [object Object] 而不是值。
  • 我忘记了您的子节点是原始字符串,因此您还需要在模板 HTML 中添加 .$value 以访问每个 addsnote 的字符串数据。
  • 哇哦。解决了它。我将如何为可观察的对象实现相同的功能?我有一个&lt;h4&gt;{{username$ | async}}&lt;/h4&gt; 并将其更改为{{username$.$value | async}} 似乎并不能解决问题。它返回 [object Object]。
  • async 管道需要位于 $value 后缀之前。您可以将其视为评估 firebase 参考值,然后在同步后从中提取 $value 数据。 {{ (username$ | async)?.$value }}? 问号确保 username$ 在尝试拉取 $value 数据之前首先被评估。
【解决方案2】:

如果您想坚持使用 Web Firebase API(没有 angularfire2),以使 addsnotes 工作,它可能看起来像这样。

ngOnInit () {
  let user = firebase.auth().currentUser;

  // Used ES6 arrow function instead, which is built into Typescript
  setTimeout(() => {
    // Make sure user and user.uid are defined
    if (user && user.uid) {
      let userRef = firebase.database().ref(`users/${user.uid}`);
      userRef.once('value', (snapshot) => {
        let userInfo = snapshot.val() || {};
        this.username = userInfo['username'];
        this.addsnotes = [];

        // Traverse each child for 'addnote'
        snapshot.child('addnote').forEach((childSnapshot) => {
          let addnoteKey = childSnapshot.key,
              addnote = childSnapshot.val();

          addnote['id'] = addnoteKey;  // Saving the reference key if you want reference it later
          self.addsnotes.push(addnote);
        });
      }
    }
  }, 1000);
}

【讨论】:

  • 老实说,我并不反对 AngularFire 2。这对我来说很多都是新的,所以我不一定知道要问的正确问题。
猜你喜欢
  • 2018-01-22
  • 2018-11-15
  • 2020-05-19
  • 2017-03-05
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
相关资源
最近更新 更多