Angular 2 firebase数据库服务

时间:2017-05-11 21:43:49

标签: angular firebase firebase-realtime-database

我想在一个完成所有数据库工作的Angular2应用程序中提供服务。我看到的所有教程都使用http而不是firebase,所以它们并没有真正的帮助。我有服务构造函数从数据库中提取我需要的数据,但是当页面试图从服务获取数据时,由于数据库调用还没有完成,它没有得到任何结果。我开始感觉像是this post,在将网络调用放入服务中没有任何意义,它们都应该是每个控制器中的重复代码,而不是将所有数据库代码放入1项服务。这是我的文件:

lesson.service.ts

import { Injectable, OnInit } from '@angular/core';
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';

export class Lesson {
  constructor(public id: number, public buttons: Object[]) {  }
}

@Injectable()
export class LessonService implements OnInit {

  private lessons: Lesson[] = [];
  constructor(public db: AngularFireDatabase) {
  }

  ngOnInit() {
    this.db.object('/lessons', { preserveSnapshot: true }).subscribe(lessons => {
      lessons.forEach(lesson => {
        this.lessons.push(new Lesson(
          lesson.key,
          lesson.val()['buttons']
        ));
      });
    });
  }

  getLessons() {
    console.log('getting lessons', this.lessons);
    return this.lessons;
  }

  getLesson(id: number): Lesson {
    // return new Promise()
    console.log('getLesson', this.lessons);
    return this.lessons.filter(lesson => {
      return lesson.id === id;
    })[0];
  }
}

lesson.ts

import { Component, OnInit, Input } from '@angular/core';
import { Lesson, LessonService } from '../lesson.service';

@Component({
  selector: 'lesson',
  templateUrl: './lesson.html',
  styleUrls: ['./lesson.scss']
})
export class LessonComponent implements OnInit {
  @Input() lessonID: number = 0;

  lesson: Lesson;
  constructor(public service: LessonService) {  }

  ngOnInit() {
    this.lesson = this.service.getLesson(this.lessonID);
    console.log('view lessons', this.lesson);
  }
}

lesson.html

<lesson [lessonID]="selectedId"></lesson>

当我尝试加载课程组件时,它发现没有课程​​,因为this.lessons没有从服务的构造函数中填写数据库。唯一的解决方案&#39;我看到的是删除课程服务,并在每次页面加载时进行数据库调用,这在我看来是无法实现单页面应用程序的目的。

2 个答案:

答案 0 :(得分:0)

在你的ngOnInit中调用getLesson可能不是一个好主意 您注入的服务可能仍在初始化。

我之前的代码遇到了同样的问题,但在将代码移到后 ngAfterViewInit(),它修复了问题。

import { Component, OnInit, AfterViewInit } from '@angular/core';
...
...

export class LessonComponent implements OnInit, AfterViewInit {
  @Input() lessonID: number = 0;

  lesson: Lesson;
  constructor(public service: LessonService) {  }

  ngOnInit() {

  }

  ngAfterViewInit() {
   this.lesson = this.service.getLesson(this.lessonID);
    console.log('view lessons', this.lesson);
  }
}

答案 1 :(得分:0)

我想我发布了错误的ts和html文件,但仍然存在我发布的文件的问题。您可以通过这些文件更多地查看问题,这就是我要解决的问题。我从视图中调用一个函数,一直到服务。我猜这是一个不好的做法,但这是我发现的唯一工作。

<强> lesson.service.ts

import { Injectable, OnInit } from '@angular/core';
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';

export class Lesson {
  constructor(public id: number, public buttons: Object[]) {  }
}

@Injectable()
export class LessonService implements OnInit {

  private lessons: Lesson[] = [];
  public buttons: object[];
  constructor(public db: AngularFireDatabase) {
    this.db.object('/lessons', { preserveSnapshot: true }).subscribe(lessons => {
      this.lessons = [];
      lessons.forEach(lesson => {
        this.lessons.push(new Lesson(
          lesson.key,
          lesson.val()['buttons']
        ));
      });
    });
  }

  ngOnInit() {
  }

  getLessons() { return this.lessons; }

  getLesson(id: number): Lesson {
    return this.lessons.filter(lesson => {
      return lesson.id === id;
    })[0];
  }

}

<强> lesson.ts

    import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Lesson, LessonService } from './lesson.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  private lessons: Lesson[];
  private lesson: Lesson = new Lesson(0, []);
  private errorMessage: string;
  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private service: LessonService
  ) {}

  getLessons() { return this.service.getLessons(); }

  gotoLesson(id) { this.router.navigate(['/lesson', id]); }

  getButtons() { return this.service.buttons; }

  doCLick(btnID) {
    console.log('clicked', btnID);
  }
}

<强> lesson.html

<md-toolbar>
  <button md-button routerLink="" routerLinkActive="active">Home</button>
  <button md-button [mdMenuTriggerFor]="lessonsMenu">Lessons </button>
  <md-menu #lessonsMenu="mdMenu" [overlapTrigger]="false">
    <button md-menu-item *ngFor="let lesson of getLessons()" (click)="gotoLesson(lesson.id)">Lesson {{lesson.id}}</button>
  </md-menu>
  <span class="toolbar-spacer"></span>
  <button md-mini-fab color="primary" *ngFor="let button of getButtons()" (click)="doClick(button.id)" style="margin-right: 10px;">
    <md-icon>{{button.icon}}</md-icon>
  </button>
  <button md-mini-fab style="margin-left: 10px;">
    <md-icon>search</md-icon>
  </button>
</md-toolbar>