2017-04-09 75 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更新后的答案,然后再试一次 –