2017-03-08 56 views
0

我有一个Angular2服务,如下所示。我正在尝试将此用作多个组件之间的共享服务。如果很重要,组件将直接绑定到public booksselectedBook properties我想缓存图书列表和当前选定的图书在服务上,只有在第一次调用时才会调用这些图书。Angular2在数组填充之前试图获取数组中的项目

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 

@Injectable() 
export class BookService { 

    public books: Book[]; 
    public selectedBook: Book; 

    constructor(private http: Http, 
     private router: Router) { 

     this.http.get('/api/book/list') 
      .subscribe(result => this.books = result.json() as Book[]); 
    } 

    public getBooks() { 
     return this.books; 
    } 

    public setSelectedBook(id) { 
     this.selectedBook = this.books.filter(x => x.id == id)[0]; 
    } 
} 

的问题是,有时我试图读取数组或致电setSelecteBook(id)前阵实际上是稀少,这会导致系统崩溃。我一直在试图找到一个如何使用Observables的例子,但我无法找到足够接近我的方案来弄清楚如何适应它来解决我的问题。

+0

您需要在构造函数中初始化'books':'this.books = []' –

+0

这只会延迟过去这一点的崩溃。我需要一些东西来等待books数组完成填充,然后设置选定的书籍。 –

回答

0

这不会初始化一个数组,它只是告诉TypeScript编译器这个特定属性是这种类型的。要实际拥有一个数组,您不必对undefined进行初始化。通过这种方式,filter功能将工作:

@Injectable() 
export class BookService { 

    public books: Book[] = []; 
    //... 
} 
2

你可以用一个空数组初始化构造函数中的数组的书籍。

您还可以在访问数组之前做一个解决方法并检查长度。

public setSelectedBook(id) { 
    if(this.books.length > 0) { 
     this.selectedBook = this.books.filter(x => x.id == id)[0]; 
    } 
} 
+1

Typescript没有安全评估操作符'?' –

+0

@ChristopherMoore对于操作员是正确的。但是,我写出了空值和长度检查的很长一段路,它所做的只是导致应用程序崩溃超过这一点;它被调用时根本不会设置选定的书。我需要一些东西让它等待书籍[]完成填充,然后设置选定的书籍。 –

0

作为一个更干净的解决方案,我将订阅您的book-detail组件,例如服务方法getBooksList。

使用this.bookService.getBooksList执行api调用,并在数组加载后立即选择所需的书。

+0

我想我遵循你所说的,但我可以使用一些代码来澄清。另外,每次选择的书籍更改时,我都不想打电话来从服务器填充书籍[]。 –

+0

你可以看看我的这个回购,在这里: https://github.com/dkiriakakis/ng2-photoalbum 看看/src/app/components/photo-detail.component.ts – dkiriakakis