简体   繁体   English

从服务到组件数组的角度

[英]Angular from service to component array

I'm struggling with Angular Services and can't find out what's the issue. 我在Angular Services上挣扎,无法找出问题所在。

I'm working on a book app (with Promises). 我正在开发一个图书应用程序(使用Promises)。 For efficiency reasons, I'm refactoring my code with service injection. 出于效率方面的考虑,我正在使用服务注入重构代码。 I use the service for all the http requests (there's a rest service behind), the data are correctly retrieved in the service but there's no way to get it in the component. 我对所有http请求都使用了该服务(后面有一个rest服务),在该服务中可以正确检索数据,但是无法在组件中获取它。 To check if it was done correctly i've added a console.log in the service promise ( populateBookList() ). 为了检查它是否正确完成,我在服务承诺(populateBookList())中添加了console.log。 The console shows the correct list. 控制台显示正确的列表。

I also added a console.log in my component to see the list, and it's empty. 我还在组件中添加了console.log来查看列表,该列表为空。 Moreover, the component book list is loaded before the service one. 而且,组件书列表在服务一之前被加载。 I know there's something fishy but can't figure out where >_< 我知道这里有些鱼,但是不知道> _ <

Any clue, advice, [other] would be really appreciated! 任何线索,建议,[其他]将不胜感激! Thank you guys! 感谢大伙们!

This is my component : 这是我的组件:

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(){        
    }

}

This is my service 这是我的服务

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;
    }
}

Change you two function to this : 将您的两个功能更改为:

 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;
        });
    }

And you will get your expected result. 这样您将获得预期的结果。

Another solution is to switch from Promises to map. 另一个解决方案是从Promises切换到map。

In my case, I had to get a Json for a known object. 就我而言,我必须为已知对象获取一个Json。 First the service! 首先服务! To do so, I call my RS to retrieve a JSON typed as Observable>: 为此,我调用RS来检索类型为Observable>的JSON:

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

The extractData method handles the response (I used it as a method by itself because I'm gonna reuse it later): extractData方法处理响应(我自己将其用作方法,因为稍后我会重用它):

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

Secondly my component. 其次是我的组件。 I add the service to my providers in my decoractor: 我将服务添加到我的装饰器中的提供者中:

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

Instantiate it in the constructor : 在构造函数中实例化它:

constructor(private httpService:HttpService){}

And then subscribe (as showed by Vivek Doshi, thanks again!) to my service method, with error and success handling : 然后订阅(如Vivek Doshi所示,再​​次感谢!)我的服务方法,并进行了错误处理和成功处理:

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 !'})) 
    }

For later reference the subscribe works as follows : componentORservice.method().subscribe(data handling, error handling, success handling). 供以后参考,subscribe的工作方式如下:componentORservice.method()。subscribe(数据处理,错误处理,成功处理)。

Thanks again! 再次感谢!

And here's the full code: 这是完整的代码:

Service : 服务内容:

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()
    }
}

And the component: 和组件:

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 !'})) 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM