2016-10-10 14 views
5

Tôi đang sử dụng CLI góc + Firebase + AngularFire2 đã cố gắng tìm ra cách truy vấn một đối tượng duy nhất từ ​​Firebase bằng cách sử dụng khóa.Truy vấn đối tượng Firebase duy nhất bằng khóa từ một dịch vụ

Luồng cơ bản sẽ là hiển thị danh sách các mục, sau đó nhấp vào một mục sẽ hiển thị chế độ xem chi tiết cho mục cụ thể đó.

Đây phải là trường hợp sử dụng khá phổ biến nhưng tài liệu AngularFire 2 dường như không đưa ra bất kỳ ví dụ rõ ràng nào về cách tôi có thể thực hiện việc này.

Tôi đang cố sử dụng dịch vụ để truy vấn các mục nhưng tôi không thể làm cho nó hoạt động.

Component

// 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(); 
    } 

} 

Dịch vụ

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; 
     }); 
    } 

} 

Trả lời

2

này nên làm điều đó:

// 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); 
 
    } 
 

 
}

Cố gắng đăng ký Đài quan sát nơi bạn cần dữ liệu. Các phương thức dịch vụ của bạn phải trả về Quan sát chứ không phải Đăng ký (trừ khi bạn thực sự có lý do chính đáng để làm khác).

+0

Cảm ơn vì điều này. Tôi đã thay đổi const thành let vì nó tiếp tục phàn nàn rằng các khai báo 'const' phải được khởi tạo và sử dụng getItem (key) thay vì ID. Tôi cũng phải khai báo mục riêng tư = {}. Hiện tại, nó đang hoạt động tuy nhiên tôi bị trễ 5-7 giây trước khi dữ liệu xuất hiện. – LifeOnLars

+0

Phần còn lại của trang tải khá nhanh nhưng tổng thời gian là 10-11 giây. Không chắc chắn nếu đó là thiết lập dev địa phương đó là chậm hoặc nếu điều này chỉ không phải là một cách rất tốt để truy vấn một đối tượng. Số lượng dữ liệu là tầm thường chỉ có 8 nút văn bản trong dữ liệu mẫu. Chế độ xem danh sách tải cùng một dữ liệu vào lúc này và nhanh hơn rất nhiều. Có phải chúng tôi không muốn tìm nạp các đối tượng bằng $ key từ Firebase không? – LifeOnLars

+0

Đó là vấn đề CLI https://github.com/angular/angular-cli/issues/1980, khi bạn tải lên ứng dụng biên dịch trước lên máy chủ, nó sẽ nhanh chóng. Bạn có thể kiểm tra trong Dev Tools> Network, sau đó lọc để chỉ hiển thị lưu lượng WebSocket (WS) ... – Sasxa

Các vấn đề liên quan