无法在Angular 2中获取init上的Ajax数据

时间:2017-07-26 14:41:48

标签: angular

我确定问题是关于异步,但我找不到解决方案。我创建了一个获取JSON数据数组的服务。在我的组件中,我想在加载页面时显示此数据。 加载页面时我没有获得任何数据,但是我创建了一个按钮,并在其onclick事件上添加了相同的功能。我在点击事件上获得了数据。我究竟做错了什么?

我的组件

import { Component } from '@angular/core';
import {PostService} from './post.service';

@Component({
  selector: 'app-root',
  template: `

  {{test}}
  <ul>
    <li *ngFor="let item of jsonArray">
    {{item.title}} a
    </li>

  </ul>
  <button on-click="onClick()">button</button>
  `


})
export class AppComponent {
  test;
  jsonArray : any[];
  constructor(private _postService : PostService){


  }

  onClick(){
    this.jsonArray = this._postService.getPosts();
    this.test = "clicked";
  }

  ngOnInit(){
     this.jsonArray = this._postService.getPosts();
     this.test = "init";

   }

}

和我的服务类

import {Http} from '@angular/http'
import 'rxjs/add/operator/map';
import {Injectable} from '@angular/core';


@Injectable()
export class PostService {

    private _url = "https://jsonplaceholder.typicode.com/posts";

    jsonArray: any[];
    getPosts():any[]{
        //return this._http.get(this._url).map(res =>res.json());
         this._http.get(this._url).subscribe(response => {
           this.jsonArray = response.json();
           console.log(response.json());
           console.log("jsonArray",this.jsonArray);
        });

        return this.jsonArray;
    }

    createPost(post){
        return this._http.post(this._url,JSON.stringify(post)).map(res =>res.json());
    }
    constructor(private _http:Http ){

    }




}

1 个答案:

答案 0 :(得分:2)

您的服务有两个问题:

  1. 您的return在回调之外,因此将返回初始空数组
  2. 即使它不在外面,你也不能subscribe返回数据。
  3. 我建议您阅读异步性:How do I return the response from an asynchronous call?

    How do I return the response from an Observable/http/async call in angular2?在更多Angular场景中解释了这种行为。

    同时阅读 official tuto of http

    话虽如此,很快就说 - 你需要map在服务中,subscribe在组件中。

    关于你的问题:

      

    我在页面加载时没有获得任何数据,但是我创建了一个按钮,并在其onclick事件上添加了相同的功能。我在点击事件上获得了数据。

    让我们深入了解您的服务方法,看看发生了什么:

    getPosts():any[]{
         this._http.get(this._url).subscribe(response => {
           // hey, I'm doing this request now, but I don't know how long it will take
           this.jsonArray = response.json();
           console.log(response.json());
           console.log("jsonArray",this.jsonArray);
        });
        /* okay, so I fired the above request, I won't wait until it is complete, 
           I'll just execute the below while I am waiting!*/
        return this.jsonArray;
    }
    

    因此,当您在OnInit上触发请求时,它会执行http请求,并且在执行时它会在http请求执行完之前返回this.jsonArray

    所以现在当你点击按钮时,它会重新启动http请求,在它再次完成之前,会再次返回this.jsonArray。但是,嘿,现在我们实际上已经从之前的请求获得了值,所以这就是为什么你得到的数据就好了!

    正如前面提到的,无论如何你都无法从subscribe返回数据,即使它是在回调中也是如此:

    getPosts():any[]{
         return this._http.get(this._url).subscribe(response => {
            ....
            return this.jsonArray; // WON'T WORK!
        });
    }
    

    所以你可以做的是从map返回数据,所以:

    <强>服务

    getPosts():any[]{
         this._http.get(this._url)
           .map(res => res.json())
        });
    }
    

    <强>组件:

    ngOnInit(){
      this._postService.getPosts()
        .subscribe(data => this.jsonArray = data)
    }
    

    真的建议您仔细阅读所提供的链接并仔细阅读:)