2017-04-09 76 views
0

我正在與角服務苦苦掙扎,無法找出問題所在。從角度服務到組件陣列

我正在開發一本書應用程序(與承諾)。出於效率原因,我使用服務注入來重構我的代碼。我對所有的http請求使用該服務(後面有一個休息服務),數據可以在服務中正確檢索,但無法在組件中獲取。 要檢查它是否正確完成,我已在服務承諾(populateBookList())中添加了console.log。 控制檯顯示正確的列表。

我還在我的組件中添加了一個console.log來查看列表,它是空的。此外,組件書籍列表在服務之前加載。 我知道有什麼可疑的,但不知道哪裏> _ <

任何線索,建議,[其他]將非常感激!感謝你們!

這是我的組件:

import { Component, OnInit, Input } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Book } from '../domain/book'; 
import { Message } from 'primeng/primeng'; 
import { Author } from '../domain/author'; 
import { HttpService } from './service/http.service'; 
import { Observable } from 'rxjs/Observable'; 

@Component({ 
    selector:'lib-book', 
    templateUrl:'./book.component.html', 
    providers: [HttpService] 
}) 

export class BookComponent implements OnInit{ 
     _httpService: HttpService; 
     urlRef:String; 
     books:Array<Book>; 
     authorList:Array<Author>; 

     public msgs:Message[]=[]; 

    constructor(private httpService:HttpService, private http:Http){ 
     this._httpService = httpService; 
     this._httpService.populateBookList(this.msgs); 
     this.books = this._httpService.getBooks(); 

    } 

    ngOnInit(){   
    } 

} 

這是我的服務

import { Injectable } from "@angular/core"; 
import { Book } from '../../domain/book'; 
import { Http } from '@angular/http'; 
import { Author } from '../../domain/author'; 

import 'rxjs/add/operator/toPromise'; 
import 'rxjs/add/operator/map'; 
import { Observable } from "rxjs/Observable"; 

@Injectable() 
export class HttpService{ 
private urlRef:String = "http://localhost:8080/Librarian-1.0/ws/"; 
private bookList:Array<Book>; 

    constructor(private http:Http){ 
     this.bookList = new Array<Book>(); 
    } 

    populateBookList(msgs){ 
     this.http.get(this.urlRef+"book") 
       .toPromise() 
       .then(response => this.bookList = response.json() as Array<Book>) 
       .then(() => console.log(this.bookList)) 
       .then(() => msgs.push({severity:'info', summary:'Book list',detail:'Loaded succesfully !'})) 
       .catch(() => msgs.push({severity:'error', summary:'Book list',detail:'Can not load list.'})); 
    } 

    getBooks():Book[]{ 
     return this.bookList; 
    } 
} 
+3

你是做一個異步操作,但要同步做作業。含義:當您調用'getBooks'時,來自'populateBookList'的數據還沒有到達。 'populateBookList'中的'http.get'將會在2秒內得到列表,但是在請求'populateBookList'後立即請求'getBooks'中的書。 – echonax

回答

0

另一種解決方案是從Promise切換到地圖。

在我的情況下,我必須得到一個Json的一個已知對象。 首先服務! 要做到這一點,我把我的RS檢索一個JSON類型爲可觀察>:

getBooks():Observable<Book[]>{ 
     return this.http.get(this.urlRef+"book").map(this.extractData); 
    } 

的ExtractData由方法處理響應(我用它作爲一種方法本身,因爲我稍後會再使用它):

extractData(res: Response){ 
     return res.json() 
    } 

其次我的組件。 我服務添加到我的供應商我decoractor:

@Component({ 
    selector:'lib-book', 
    templateUrl:'./book.component.html', 
    providers: [ HttpService ] 
}) 

初始化它在構造函數中:

constructor(private httpService:HttpService){} 

然後訂閱(如維韋克多希再次表明,謝謝!)我的服務方法,錯誤和成功處理:

ngOnInit(){ 
    this.httpService.getBooks() 
     .subscribe(
      // opération à réaliser 
      data => {this.books = data}, 
      // gestion de l'erreur 
     ()=> this.msgs.push({severity:'error', summary:'Book list',detail:'Can not load list.'}), 
      // gestion de la réussite 
     () => this.msgs.push({severity:'info', summary:'Book list',detail:'Loaded succesfully !'})) 
    } 

供以後參考訂閱的工作原理如下: componentORservice.method()。訂閱(數據處理,錯誤處理,成功處理)。

再次感謝!

而這裏的全碼:

服務:

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

import { Observable } from "rxjs/Observable"; 

import { Author } from '../../domain/author'; 
import { Book } from '../../domain/book'; 

@Injectable() 
export class HttpService{ 
private urlRef:String = "http://your_url"; 

    constructor(private http:Http){ 
    } 

    getBooks():Observable<Book[]>{ 
     return this.http.get(this.urlRef+"book").map(this.extractData); 
    } 

    getAuthors():Observable<Author[]>{ 
     return this.http.get(this.urlRef+"author").map(this.extractData); 
    } 

    extractData(res: Response){ 
     return res.json() 
    } 
} 

和組件:

import { Component, OnInit, Input } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Message } from 'primeng/primeng'; 

import { HttpService } from './service/http.service'; 
import { Observable } from 'rxjs/Observable'; 

import { Book } from '../domain/book'; 
import { Author } from '../domain/author'; 

@Component({ 
    selector:'lib-book', 
    templateUrl:'./book.component.html', 
    providers: [ HttpService ] 
}) 

export class BookComponent implements OnInit{ 
     books:Array<Book>; 
     msgs:Message[]=[]; 

    constructor(private httpService:HttpService){ 
    } 

    ngOnInit(){ 
    this.httpService.getBooks() 
     .subscribe(
      data => {this.books = data}, 
     ()=> this.msgs.push({severity:'error', summary:'Book list',detail:'Can not load list.'}), 
     () => this.msgs.push({severity:'info', summary:'Book list',detail:'Loaded succesfully !'})) 
    } 
} 
0

改變你們兩個功能是:

populateBookList(msgs){ 
     return this.http.get(this.urlRef+"book").map(response => { 
      this.bookList = response.json() as Array<Book>; 
      console.log(this.bookList); 
      msgs.push({severity:'info', summary:'Book list',detail:'Loaded succesfully !'} 
      return this.bookList; 
     }).catch(() => msgs.push({severity:'error', summary:'Book list',detail:'Can not load list.'}));; 
    } 


    constructor(private httpService:HttpService, private http:Http){ 
     this._httpService = httpService; 
     this._httpService.populateBookList(this.msgs).subscribe(res => { 
      this.books = res; 
     }); 
    } 

,你會得到您預期的結果。

+0

只需要一些精度,在populateBookList()中,this.bookList引用一個服務變量的權利? 有了這兩個元素(服務中的populateBookList和組件中的構造函數),當我執行console.log()完成訂閱時,仍然會收到一個「undefined」:s – raik

+0

是的,請問,控制檯.log「res」from「subscribe(res =>」,所以我幫你更多。 –

+0

請問你檢查mu更新後的答案,然後再試一次 –