【问题标题】:HTTP: Angular 2+TS How to use Observables in HTTPHTTP:Angular 2+TS 如何在 HTTP 中使用 Observables
【发布时间】:2016-09-29 03:11:28
【问题描述】:

我从 angular.io 中找到了一个示例。这个例子与我的应用程序非常相似,具有相同的方法。这个例子使用的是 Promises,但我使用的是 Observables。如果我使用这个示例作为参考,我的应用程序中的所有方法都可以工作,除了服务中的 getHero 方法和 HeroDetailComponent 中的 ngOnInit。所以我想知道是否有人可以帮助并将此方法转换为可观察的,因为我遇到了语法问题。这是我需要转换为 Observable 的代码和plunker

//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??        
}

编辑:我必须直接检索列表,它不适用于 return 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
}

【问题讨论】:

    标签: http angular


    【解决方案1】:

    如果您在 Observable 上调用 subscribe(),则会返回 Subscription。您不能在订阅时致电 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 在它有订阅者的新数据时调用此函数。因此,此代码不会立即执行,而是仅在可观察对象发出新数据时执行。

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

    【讨论】:

    • 谢谢! getHero 就像一个魅力,但现在我的 ngOnInit 中有一个(奇怪的?)错误。你能帮我吗?更新了我的问题!
    • 很好的解释,谢谢!一般来说,我是编码新手,我记得我在某个地方遇到过这个问题,这是 Promises 和 Observables 之间的区别之一。但我想我忘了它!再次更新问题,因为我要移动到的详细信息页面仍然抱怨它未定义!我猜你的括号太多了,或者太少了,我试着把括号放在正确的位置,但我猜还是错了?
    • 你是对的,有一个多余的。你现在在哪里得到错误? “尝试移动到详细信息页面时”是什么意思?
    • 哦,是的,忘了更好地解释自己。好吧,我的应用程序框架看起来几乎与我在问题中链接的 plunker 完全一样。所以就像那里一样,我转到“英雄”详细信息页面。但对我来说,当我尝试转到详细信息页面时,它仍然给英雄未定义。控制台在已收到 id 的详细信息组件中登录 ngOnit 但我猜订阅仍然无法正常工作???就像英雄示例一样,我尝试显示英雄的名字。
    • 好吧,我也没有。几个小时以来,我一直对这段代码视而不见。当(如果!)我弄清楚时,我一定会提供答案:)
    【解决方案2】:

    这是一种你可以做到的方式:

    //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() 返回一个包含过滤值的新数组,但你只需要一个英雄。

    【讨论】:

      猜你喜欢
      • 2017-10-09
      • 2017-09-09
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      相关资源
      最近更新 更多