【问题标题】:Ionic2/angular2 correct way of consuming serviceIonic2/angular2 正确的消费服务方式
【发布时间】:2016-06-27 23:16:34
【问题描述】:

我正在学习构建 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;

      }
}

应用截图:

所以这里的问题是:

  • 除非我点击 Fetch 按钮(它在组件中调用 getData() 函数)它不会加载数据,不知何故在组件的构造函数中必须设置数据,而不是在我调用 getData() 函数时设置。我尝试在构造函数中写this.items = this.testService.fetchData() 这一行,但它不起作用。

  • 当在另一个组件和服务中我必须附加从这个 FarmList 组件发送的 navparam 时,这个问题会变得更糟:let myUrl = 'http://jsonplaceholder.typicode.com/users/' + this.id ; 我尝试附加 this.id 在它的构造函数中设置为接收 navparam,我得到 undefined

    构造函数(私有nextService:NextService,navParams:NavParams){ this.id = navParams.get("param1"); }

我只是想在一页上列出一个列表,然后单击其中一个列表项将打开新页面,其中包含更多详细信息。我正在点击这个公开可用的 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
  • 不,我不知道。关于如何使用它的任何说明?

标签: angular ionic2


【解决方案1】:

ngOnInit 可能就是您要找的东西:

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

阅读更多angular

编辑:

由于您的 cmets,我再次查看了您的电话在做什么。在组件中,您将数据设置为从 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)
    }
}

【讨论】:

  • 当我尝试实现 Oninit 时,它给了我编译错误提示:FarmList 错误地实现了接口“Oninit”。 FarmList 类型中缺少属性 ngOninit。这是什么意思?我做的和你提到的完全一样,并参考了文档。
  • 好的,这已解决:它必须是 ngOnInit() 而不是 ngOninit(),这是一个错字。但是列表没有自动加载,我仍然需要单击按钮调用 getData()
  • 在这种情况下,您会遇到一些异步问题。我稍后会编辑答案
  • 看起来很有希望,但是我仍然没有运气!服务中的第一行给了我编译错误,所以我将其更改为: myUrl:'jsonplaceholder.typicode.com/users';并在 fetchData() 中:返回 this.http.get(this.myUrl).toPromise().then(response => response.json().data)。我按照你在组件中的建议做了,我得到 GET localhost:8100/null 404 (Not Found) & EXCEPTION: Error: Uncaught (in promise): [object Object] 错误。响应 {_body: "Cannot GET /null↵", status: 404, ok: false, statusText: "Ok", headers: Headers...} ;
  • 当我们谈论承诺时,哈哈“看起来很有希望”......抱歉,当您省略 http:// 时,将您的 myUrl 声明更改为私有 myUrl = 'jsonplaceholder.typicode.com/users' 它决定考虑到您正在从基本 url 加载资源,您遇到了解析错误,因为 let 应该在类的函数中用于声明变量,并且由于打字稿,您将“null”作为 url ......我已经更新我自己的错别字的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
相关资源
最近更新 更多