我正在学习构建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;
}
}
所以这里的问题是:
除非我单击 获取 按钮(在组件中调用getData()函数),否则它将不会以某种方式在组件的构造函数中加载数据必须设置数据,而不是在我调用getData()
函数时。我尝试在构造函数中编写this.items = this.testService.fetchData()
这一行,但它不起作用。
当在另一个组件和服务中我必须附加从此 FarmList 组件发送的navparam
时,此问题会进一步恶化:let myUrl = 'http://jsonplaceholder.typicode.com/users/' + this.id ;
我尝试追加 this.id 设置为在其构造函数中接收navparam,我得到 undefined
构造函数(private 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 ;
...
}
答案 0 :(得分:1)
ngOnInit可能就是你要找的东西:
import { OnInit} from '@angular/core';
...
export class FarmList implements OnInit {
...
ngOnInit(){
this.getData()
}
}
了解详情
修改强>
由于您的评论,我再看看您的电话在做什么。在组件中,您将数据设置为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)
}
}