2016-05-31 56 views
2

我从angular.io中找到了一个示例。这个例子与我的应用非常相似,使用了相同的方法。这个例子使用Promises,但我使用Observables。如果我使用这个例子作为参考,除了服务中的getHero方法和HeroDetailComponent中的ngOnInit之外,我已经在我的应用中使用了每种方法。所以我想知道是否有人可以帮助并将此方法转换为可观察的,因为我在语法上遇到了问题。这是我需要转换为可观察的代码和plunkerHTTP:Angular 2 + TS如何在HTTP中使用Observables

//HeroService 
    getHero(id: number) { // my id is String 
    return this.getHeroes() 
       .then(heroes => heroes.filter(hero => hero.id === id)[0]); 
    } 


//HeroDetailComponent 
    ngOnInit() { 
    if (this.routeParams.get('id') !== null) { 
     let id = +this.routeParams.get('id'); 
     this.navigated = true; 
     this.heroService.getHero(id) 
      .then(hero => this.hero = hero); 
    } else { 
     this.navigated = false; 
     this.hero = new Hero(); 
    } 
    } 

所以我想是这样的:

//HeroService 
public getHero(id: string) {  
    return this.getHeroes() 
    .subscribe(heroes => this.heroes.filter(hero => heroes.id === id)[0]); //BTW, what does this [0] mean??   
} 

编辑:我不得不居然直接检索列表,它不与工作按照以下答案中的建议返回this.heroes。工作示例:

public getById(id: string) { 
    //return this.getHeroes() <---- didn't work 
    return this.http.get('someUrl') // WORKS! 
    .map(heroes => this.heroes.filter(hero => hero.id === id)[0]);   
} 

现在我仍然遇到我的ngOnit问题,我不明白为什么!

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getById(id) 
    //console.log("retrieved id: ",id) <----- gives correct id! 
    .subscribe(hero => this.hero = hero); 
    //console.log("hero: ", this.hero); <----- gives undefined! 
} 

EDIT2,仍然得到试图移动到详细页:(我觉得你有一个支架,多在你的答案时不确定,试图寻找和获取正确的地方的括号?

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getById(id) 
    .subscribe(heroes => { 
     // this code is executed when the response from the server arrives 
     this.hero = hero 
    }); 
    // code here is executed before code from the server arrives 
    // even though it is written below 
} 

回答

2

如果你在Observable返回一个Subscriptionsubscribe()。你不能在订阅致电subscribe()

而是只使用运营商(map()),并使用subscribe()在电话会议上网站:

public getHero(id: string) {  
    return this.getHeroes() 
    .map(heroes => this.heroes.filter(hero => heroes.id === id)[0]); 
} 

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getHero(id) 
    .subscribe(hero => this.hero = hero); 
} 

在违背subscribe()map()还经营上Observable也返回一个Observable

[0]意味着只需要过滤英雄的第一项。

更新

ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this._searchService.getById(id) 
    .subscribe(searchCase => { 
     // this code is executed when the response from the server arrives 
     this.searchCase = searchCase; 
     console.log("id: ", this.searchCase); 
    }); 
    // code here is executed before code from the server arrives 
    // event though it is written below 
} 

此代码是一个函数

searchCase => { 
     // this code is executed when the response from the server arrives 
     this.searchCase = searchCase); 
     console.log("id: ", this.searchCase); 
    } 

传递给subscribe()Observable调用此功能时,它对于用户的新数据。因此,该代码不会立即执行,而只能在observable发出新数据时执行。

subscribe()之后的代码立即执行,因此在上面的函数之前执行,因此this.searchCase还没有值。

+0

谢谢! getHero就像一个魅力,但现在我在我的ngOnInit有一个(奇怪的?)错误。你能帮我吗?更新了我的问题! – Alex

+0

我更新了我的答案。 –

+0

非常好的解释,谢谢!我一般都不熟悉编码,我记得我在某个地方遇到过,这是Promise和Observables之间的区别之一。但我想我忘了它!再次更新问题,因为我正在移动的详细信息页面仍然抱怨它未定义!我想你有一个支架太多,或太少,我试图把括号放在他们的正确位置,但我想这仍然是错误的? – Alex

1

这是一种方法可以做到这一点:

//HeroService 
public getHero(id: string) {  
    return this.getHeroes() 
     .map(heroes => this.heroes.filter(hero => heroes.id === id)[0]); 
} 

//HeroDetailComponent 
ngOnInit(){ 
    let id = this._routeParams.get('id'); 
    this.heroService.getHero(id) 
     .subscribe(hero => { 
      // your code here 
     }); 
} 

[0]是一个数组访问。您正在使用它选择数组索引0上的第一个元素。你需要这个,因为Array.filter()会返回一个带有过滤值的新数组,但你只需要一个英雄。

-1

很好的答案在这里,但不得不调整他们稍微所以我加入了我自己的

服务看起来像这样...

import {Injectable}  from '@angular/core'; 
import {Http, Response} from '@angular/http'; 
import {Person} from '../models/person'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class PersonService { 
    private personsUrl = 'app/data/persons.json'; 

    constructor(private http:Http) { 
    } 

    getPersons():Observable<Person[]> { 
    return this.http.get(this.personsUrl) 
     .map(
     (res:Response) => { 
      let persons = res.json(); 
      return persons || {}; 
     } 
    ) 
     .catch(this.handleError); 
    } 

    getPerson(id:number) { 
    return this.getPersons() 
     .map(persons => persons.filter(person => person.id === id)[0]); 
    } 

    private handleError(error:any) { 
    let errMsg = (error.message) ? error.message : 
     error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
    console.error(errMsg); 
    return Observable.throw(errMsg); 
    } 
} 
+0

有什么本质的区别? –

+0

.map(persons => persons.filter(person => person.id === id)[0]); – danday74

+0

这似乎与问题无关。该过滤器行已经在问题中,并且您刚刚将'Hero'重命名为'Person'。这个答案的目的是什么? –