Ionic2/angular2 正确的服务消费方式

Ionic2/angular2 correct way of consuming service

我正在学习构建 Ionic-2 应用程序,我有一些组件使用服务进行 http 调用并获取一些数据,这些数据又将在组件中设置并最终显示在模板中。我总体上理解流程,但在编码时犯了一些逻辑错误。

我的示例组件:

export class FarmList {

  items: Object;

  constructor(private testService: TestService, public nav: NavController){}

  getData(): any {

    this.items = this.testService.fetchData()

  }

  nextView(){

    this.nav.push(Farm)

  }

  showDetails(id: Number){

    this.nav.push(Farm, {
      param1: id
    })

  }
}

我对应的服务:

@Injectable()
export class TestService{

    loading: boolean;
    data: Object;

    constructor(private http: Http){

        let myUrl = 'http://jsonplaceholder.typicode.com/users';

        this.loading = true;
        this.http.request(myUrl)
          .subscribe(
            (res: Response) => {

            this.loading=false;
            this.data=res.json();

          });

    }

    public fetchData(){

        return this.data;

      }
}

应用截图:

所以这里的问题是:

我只是想在一页上显示一个列表,然后单击其中一个列表项将打开新页面,其中包含更多详细信息。我正在点击这个公开可用的 API: http://jsonplaceholder.typicode.com/users/,然后向其附加一些数字以仅获得一个对象。

正确的做法是什么?

更新: 我可以通过简单地在服务构造函数中获取 navParams 并将其附加到 url 来解决第二个问题如下:

@Injectable()
export class NextService{

    loading: boolean;
    data: Object;
    id: Number;

    constructor(private http: Http, navParams: NavParams){

    this.id = navParams.get("param1");
    console.log("Second service fetching param: " + this.id)

        let myUrl = 'http://jsonplaceholder.typicode.com/users/' + this.id ;
...
}

ngOnInit 可能是您要找的:

import { OnInit} from '@angular/core';
...
export class FarmList implements OnInit {
    ...
    ngOnInit(){
        this.getData()
    }
}

angular

阅读更多内容

编辑:

根据您的评论,我再次查看了您的通话内容。在组件中,您将数据设置为从 fetchData 函数返回的任何内容,该函数仅返回服务中设置的数据。在调用 ngOnInit 时它只是一个空对象,几毫秒后 service.data 被更改为从您的 http 异步调用返回的任何内容。

更好的做法是遵循 Angular's Http getting started tutuorial。本质上我认为你最终会得到更像这样的东西:

服务:

@Injectable()
export class TestService{
        private myUrl: string = 'http://jsonplaceholder.typicode.com/users';
// loading: boolean; 
//move any logic that has to do with UI to the component... 
//this is more of a suggestion and has to do with MV* best practices

    constructor(private http: Http){
// I think it was in John Papa's Pluralsight video on angular 2 that said
// try to do as little as possible inside of the constructor
    }    

    public fetchData(){
//the key here is to return a promise (or observable) so that the 
//component can handle it when it gets resolved
        return this.http.get(myUrl)
               .toPromise()
               .then(response => response.json().data)
      }
}

分量:

import { OnInit} from '@angular/core';
...
export class FarmList implements OnInit {
    ...
    ngOninit(){
        this.getData()
    }
    getData(){
        this.testService.fetchData().then(data => this.items = data)
    }
}