2016-10-10 5 views
5

각도 CLI + Firebase + AngularFire2가 키를 사용하여 Firebase에서 단일 객체를 쿼리하는 방법을 알아 내려고했습니다.서비스의 키로 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; 
     }); 
    } 

} 

답변

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() { 
 
    // 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은 그렇지 않습니다.

+0

감사합니다. 나는 'const'선언을 초기화하고 ID보다는 getItem (key)을 사용해야한다는 불평을 계속하면서 const를 let으로 변경했다. 나는 또한 private item = {}을 선언해야만했다. 그러나 데이터가 나타나기 전에 나는 5-7 초의 지연을 얻는다. – LifeOnLars

+0

나머지 페이지는 매우 빠르게로드되지만 총 시간은 10-11 초입니다. 느린 로컬 설치 설정인지 또는이 방법이 개체를 쿼리하는 아주 좋은 방법이 아닌지 확실하지 않습니다. 데이터의 양은 샘플 데이터에 단지 8 개의 텍스트 노드가 있습니다. 목록보기는 현재 동일한 데이터를로드하며 훨씬 빠릅니다. Firebase에서 $ key로 객체를 가져 오는 것이 아닌가요? – LifeOnLars

+0

CLI 문제 https://github.com/angular/angular-cli/issues/1980에서 미리 컴파일 된 앱을 서버에 업로드하면 서버 속도가 빨라집니다. Dev Tools> Network를 체크 한 다음 WebSocket 트래픽 (WS) 만 표시하도록 필터링 할 수 있습니다 ... – Sasxa