2017-07-01 57 views
0

什麼我有什麼,我試圖做Angular&Firebase - 如何更新Firebase:使用服務還是組件?

  • 我有得到的從火力
  • 「相冊」的名單我已經有一些輸入字段組件添加服務新項目
  • 作爲數據的Firebase非規範化的一部分,我有兩個要更新的節點。 'AlbumLists'和'AlbumDetails'
  • 我可以使用下面的代碼更新到Firebase(不包括最底部的Firebase建議)
  • 我知道我可能需要包含另一個服務我的例子。一個相冊列表,一個專輯摘要

問題

  1. 我已經看到了一些示例代碼從火力上如何更新在多個地方的代碼,並創建兩個新節點新的密鑰。然而,我不知道這個代碼會在我目前的解決方案中出現在哪裏。它是否進入組件或服務?
  2. 如果代碼適合組件,是否值得擁有服務? (如果它可以在我的服務工作,這將是很好)

我「已經列入火力建議在最底層的方法。這將是非常美妙知道如何整合到我目前的結構。

相冊服務

import { Injectable } from '@angular/core'; 
 
import { Album } from './album.model'; 
 
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 
 

 
@Injectable() 
 
export class AlbumService { 
 
    albums: FirebaseListObservable<any[]>; 
 

 
    constructor(private database: AngularFireDatabase) { 
 
    this.albums = database.list('albums'); 
 
    } 
 

 
    getAlbums() { 
 
    return this.albums;; 
 
    } 
 

 
    addAlbum(newAlbum: Album) { 
 
    this.albums.push(newAlbum); 
 
    } 
 

 
    getAlbumById(albumId: string) { 
 
    return this.database.object('/albums/' + albumId); 
 
    } 
 

 
    updateAlbum(localUpdatedAlbum) { 
 
    var albumEntryInFirebase = this.getAlbumById(localUpdatedAlbum.$key); 
 
    albumEntryInFirebase.update({ 
 
     title: localUpdatedAlbum.title, 
 
     artist: localUpdatedAlbum.artist, 
 
     description: localUpdatedAlbum.description  
 
    }); 
 
    } 
 

 
}

Admin.component.html - 用於添加新項目

<div class="panel panel-default"> 
 
    <div class="panel-heading"> 
 
    <h3 class="panel-title">Add New Album to Inventory</h3> 
 
    </div> 
 
    <div class="panel-body"> 
 
    <div> 
 
     <div> 
 
     <label>Album Title:</label> 
 
     <br> 
 
     <input #newTitle> 
 
     </div> 
 

 
     <div> 
 
     <label>Album Artist:</label> 
 
     <br> 
 
     <input #newArtist> 
 
     </div> 
 

 
     <div> 
 
     <label>Album Description:</label> 
 
     <br> 
 
     <textarea #newDescription></textarea> 
 
     </div> 
 

 
     <button (click)="submitForm(newTitle.value, newArtist.value, newDescription.value); newTitle.value=''; newArtist.value=''; newDescription.value=''">Add</button> 
 

 
    </div> 
 
    </div> 
 
</div>

Admin.component.ts - 用於添加新項目

import { Component, OnInit } from '@angular/core'; 
 
import { Album } from '../album.model'; 
 
import { AlbumService } from '../album.service'; 
 
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 
 

 

 

 
@Component({ 
 
    selector: 'app-admin', 
 
    templateUrl: './admin.component.html', 
 
    styleUrls: ['./admin.component.css'], 
 
    providers: [AlbumService] 
 
}) 
 
export class AdminComponent implements OnInit { 
 

 

 
    constructor(
 
    private albumService: AlbumService 
 
) { } 
 

 
    ngOnInit() { 
 
    } 
 

 
    submitForm(title: string, artist: string, description: string) { 
 

 
    var newAlbum: Album = new Album(title, artist, description); 
 
    this.albumService.addAlbum(newAlbum); 
 
    console.log(newAlbum); 
 

 
    } 
 

 
}

這是代碼火力點建議爲每個新節點更新信息,並推動通過獨特的火力鍵

// A post entry 
 
var postDate = { 
 
    author: username, 
 
    body:body, 
 
    title:title 
 
} 
 

 
// Get a key for a new post 
 
var newPostKey = firebase.database().ref().child('posts').push().key; 
 

 
// Write the new post's data simultaneously in the posts list and the user's post list 
 
var udpates = {} 
 
updates['/posts' + newPostKey] = postData; 
 
updates['/users-posts/' + newPostKey] = postData; 
 

 
return firebase.database().red().update(updates);

編輯:

管理組件。ts

下面的代碼會導致圖像中出現的內容。所以我們變得非常接近。每當我包含'(key)'時,拋出以下錯誤:

[ts]無法調用其類型缺少呼叫簽名的表達式。類型「FirebaseListObservable」沒有兼容的呼叫簽名。

submitForm(title: string, artist: string, description: string) { 
 

 
    var newAlbum: Album = new Album(title, artist, description); 
 
    //this.albumService.addAlbum(newAlbum); 
 
    console.log(newAlbum); 
 

 
    var albumListObject = { 
 
     title:title, 
 
     description:description 
 
    } 
 

 
    this.albumService.albums.push(newAlbum).then(({key}) => this.albumService.summariesObject.push(albumListObject)); 
 

 
    } 
 

 
}

相冊服務

import { Injectable } from '@angular/core'; 
 
import { Album } from './album.model'; 
 
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database'; 
 

 
@Injectable() 
 
export class AlbumService { 
 
    albums: FirebaseListObservable<any[]>; 
 
    summariesObject: FirebaseObjectObservable<any[]>; 
 

 
    constructor(private database: AngularFireDatabase) { 
 
    this.albums = database.list('albums'); 
 
    this.summariesObject = database.object('albumList'); 
 
    } 
 
}

enter image description here

問題

  1. 在我的相冊服務,將我需要有兩個albumList及摘要2個火力點參考?或者他們會在兩種不同的服務?
  2. 爲什麼(鍵)文本導致錯誤?

回答

3

很多這是一個偏好和風格的問題。話雖如此,在一個或多個服務中分離特定於Firebase的操作幾乎總是一個更好的主意。

然而,我不知道它是真的值得定義很多方法,如addAlbum我個人的偏好是讓服務只提供FirebaseListObservable,並直接在組件中執行.push。有些人可能會找到一個額外的抽象層 - 例如,他們可能會繪製一個場景,您將從Firebase切換到其他場景。但是,實際上,這是不太可能的,如果你確實決定這麼做,那麼這種簡單的抽象層對你來說無論如何不會有多大的幫助。

作爲一個小點,如果你有一個專用於專輯的整個服務,我不覺得有必要在所有方法名稱中重複單詞「專輯」。爲什麼不只是add()

用於推動一個新對象到一個節點,然後使用相同的密鑰創建一個子節點的其他地方的標準圖案是

this.albumService.list.push(albumData) 
    .then(({key}) => this.albumService.summariesObject(key).update(stuff)); 

換句話說,該數據推到列表,生成新的鍵,等待承諾將使用包含密鑰的快照完成,然後使用必要數據在某個其他節點內使用該密鑰更新FirebaseObjectObservable。儘量保留在AngularFire範例中,儘管有些情況下你必須回退到firebase.database().ref種事情。

+0

嗨Torazaburo - 感謝您花時間回覆。非常感激。清除.firebase.database會很好(主要是因爲無論如何,我一直在'找不到Firebase')。如果它不是太麻煩,你能告訴我一個例子,說明你的代碼如何適合我的上面?(正如前面提到的,對於所有這些都很新穎,並試圖讓我的頭腦如何將所有片段合在一起) – MegaTron

+0

想象一下,在提交表單方法中,我希望將標題,藝術家和描述推送到Firebase專輯節點,並且我想將標題和藝術家推送到albumsList firebase節點。然而,相冊> key/albumsList>鍵(其中兩個鍵都是相同的) – MegaTron

+0

另外,我更喜歡讓服務提供數據並推動組件的想法。我認爲這將是相同的更新 – MegaTron