2017-07-01 78 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