我正在尝试Angular2,并一直在关注他们的教程.
我目前有一个从json服务器获取数据的服务:
import { Injectable } from '@angular/core'; import { Http,Response } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { User } from './user'; @Injectable() export class UserService { constructor(private http: Http) {} private usersUrl = 'http://localhost:3000/users'; getUsers(): Observable<User[]> { return this.http.get(this.usersUrl) //the request won't go out until something subscribes to the observable .map(this.extractData) .catch(this.handleError); // pass an error message back to the component for presentation to the user but only if we can say something the user can understand and act upon } private extractData(response: Response) { if (response.status < 200 || response.status >= 300) { throw new Error('Bad response status: ' + response.status); } let body = response.json(); // parse JSON string into JavaScript objects return body.data || { }; } private handleError (error: any) { // In a real world app,we might send the error to remote logging infrastructure before returning/sending the error let errMsg = error.message || 'Server error'; // transform the error into a user-friendly message return Observable.throw(errMsg); // returns the message in a new,Failed observable } }
我的组件:
import { Component,OnInit } from '@angular/core'; import { User } from '../common/user/user'; import { UserService } from '../common/user/user.service'; @Component({ selector: 'app-nav',templateUrl: '/app/nav/nav.component.html',styleUrls: ['/app/nav/nav.component.css'] }) export class NavComponent implements OnInit { errorMsg: string; users: User[]; constructor(private userService: UserService) { } getUsers() { this.userService .getUsers() .subscribe( function(users) { console.log('users ' + users); this.users = users; console.log('this.users ' + this.users); },function(error) { console.log('error ' + error); }); // users => this.users = users,// error => this.errorMsg = <any>error); } ngOnInit() { this.getUsers(); console.log('ngOnit after getUsers() ' + this.users); } }
我的问题是,在getUsers()调用完成后,订阅函数返回的数据没有被传递/分配给我的Component属性’users’.我知道数据是从服务方法调用返回到组件的,因为我能够在userService().getUsers方法中记录数据.奇怪的是,我的ngOnInit上的console.log调用首先在我的开发控制台上打印在我的getUsers方法中的console.logs之前,尽管我首先调用了getUsers:
ngOnInit() { this.getUsers(); console.log('ngOnit after getUsers() ' + this.users); }
Dev控制台截图:
这是因为this.getUsers()然后this.userService.getUsers().subscribe(…)仅调度一个调用来向服务器发出请求.最终,当来自服务器的响应到达时(console.log(‘ngOnit在getUsers()’this.users之后);在调用服务器之前已经执行了),然后执行传递给subscribe()的函数.
原文链接:https://www.f2er.com/angularjs/240609.html这应该做你想要的:
getUsers() { return this.userService .getUsers() .map( (users) => { console.log('users ' + users); this.users = users; console.log('this.users ' + this.users); }) .catch((error) => { console.log('error ' + error); throw error; }); // users => this.users = users,// error => this.errorMsg = <any>error); } ngOnInit() { this.getUsers().subscribe(_ => {; console.log('ngOnit after getUsers() ' + this.users); }); }
在getUsers()中,我使用map()而不是subscribe,因此我们可以稍后订阅,以便能够在响应到达时执行代码.
然后在ngOnInit()中我们使用subscribe()(必须使用subscribe(),否则将永远不会执行http.get())并在响应到达时传递我们想要执行的代码.
我还将function()更改为()=>.这种方式适用于以下代码块()=> {…},否则就不会.
别忘了添加
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch';
否则这些运算符将无法识别.