【问题标题】:Query single Firebase object by key from a service从服务中按键查询单个 Firebase 对象
【发布时间】:2016-10-10 14:29:37
【问题描述】:

我正在使用 Angular CLI + Firebase + AngularFire2 一直试图弄清楚如何使用密钥从 Firebase 查询单个对象。

基本流程是显示项目列表,然后单击项目将显示该特定项目的详细信息视图。

这应该是一个非常常见的用例,但 AngularFire 2 文档似乎没有给出任何明确的例子来说明我如何做到这一点。

我正在尝试使用服务来查询项目,但我无法让它工作。

组件

// COMPONENT

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { AngularFire, FirebaseObjectObservable} from 'angularfire2';
import { Subscription } from 'rxjs';
import { ItemsService } from '../items.service';

@Component({
  selector: 'app-item-detail',
  templateUrl: './item-detail.component.html',
  styleUrls: ['./item-detail.component.css']
})
export class ItemDetailComponent implements OnInit, OnDestroy {

  private subscription: Subscription;
  private item;

  constructor(private af: AngularFire,
              private route: ActivatedRoute,
              private router: Router,
              private itemsService: ItemsService) { }


  ngOnInit() {
    this.subscription = this.route.params.subscribe(
      (param: any) => {
        let id = param['id'];
        console.log('Key: '+ id);
        this.item = this.itemsService.getItem(id);
      }
    );
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

服务

import { Injectable } from '@angular/core';
import { Headers, Http, Response } from "@angular/http";
import { AngularFire, FirebaseObjectObservable, FirebaseListObservable, FirebaseApp } from 'angularfire2';
import 'rxjs/Rx';

@Injectable()
export class ItemsService {

  private items: FirebaseListObservable<any[]>;
  private item: FirebaseObjectObservable<any>;

  constructor(private af: AngularFire) {}

  getItems(num) {
    this.items = this.af.database
      .list('/items', { query: { limitToLast: num | 20} } )
      .map( (arr) => { return arr.reverse() } ) as FirebaseListObservable<any[]>;
    return this.items;
  }

  getItem(id: string) {
    this.item = this.af.database.object('/items/'+id);
    this.item.subscribe(item => {
        console.log(item);
        return item;
      });
  }

}

【问题讨论】:

    标签: angular firebase firebase-realtime-database angularfire2


    【解决方案1】:

    应该这样做:

    // COMPONENT
    
    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Router, ActivatedRoute, Params } from '@angular/router';
    import { AngularFire, FirebaseObjectObservable} from 'angularfire2';
    import { Subscription } from 'rxjs';
    import { ItemsService } from '../items.service';
    
    @Component({
      selector: 'app-item-detail',
      templateUrl: './item-detail.component.html',
      styleUrls: ['./item-detail.component.css']
    })
    export class ItemDetailComponent implements OnInit, OnDestroy {
    
      private subscription: Subscription;
      private item;
    
      constructor(private af: AngularFire,
                  private route: ActivatedRoute,
                  private router: Router,
                  private itemsService: ItemsService) { }
    
      
      ngOnInit() {
        // get id synchronously, don't need it more then once
        const key: string;
        this.route.params.take(1).subscribe(param => key = param["id"]);
        this.subscription = this.itemsService.getItem(id)
          .subscribe(item => this.item = item)
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    
    }
    
    
    @Injectable()
    export class ItemsService {
      ...
    
      getItem(id: string) {
    return this.af.database.object('/items/'+id);
      }
    
    }

    尝试订阅需要数据的 Observable。您的服务方法应该返回 Observable 而不是 Subscription(除非您真的有充分的理由不这样做)。

    【讨论】:

    • 谢谢。我将 const 更改为 let,因为它一直抱怨必须初始化“const”声明并使用 getItem(key) 而不是 ID。我还必须声明 private item = {}。它现在正在工作,但是在数据出现之前我得到了 5-7 秒的延迟。
    • 页面的其余部分加载速度非常快,但总时间约为 10-11 秒。不确定是本地开发设置速度慢还是这不是查询对象的好方法。数据量微不足道,示例数据中只有 8 个文本节点。列表视图此时加载相同的数据,而且速度要快得多。我们不是要通过 $key 从 Firebase 获取对象吗?
    • 这是 CLI 问题github.com/angular/angular-cli/issues/1980,一旦您将预编译的应用程序上传到服务器,它会很快。您可以检查开发工具>网络,然后过滤以仅显示 WebSocket 流量(WS)...
    • 我确实检查了网络设置,问题不是构建的大小(即使它是 4MB)。该应用程序在大约 4 秒内加载,然后 Websocket 又需要 8-10 秒才能完成,我认为这很奇怪。我会尝试上传它,看看 websocket 流量是否仍然存在相同的延迟
    猜你喜欢
    • 1970-01-01
    • 2019-06-23
    • 2011-02-19
    • 2011-01-22
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多