Angular2 – OnInit:从Service’subscribe函数返回的值未分配给Component字段/ s

前端之家收集整理的这篇文章主要介绍了Angular2 – OnInit:从Service’subscribe函数返回的值未分配给Component字段/ s前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试Angular2,并一直在关注他们的教程.

我目前有一个从json服务器获取数据的服务:

  1. import { Injectable } from '@angular/core';
  2. import { Http,Response } from '@angular/http';
  3.  
  4. import { Observable } from 'rxjs/Observable';
  5.  
  6. import { User } from './user';
  7.  
  8. @Injectable()
  9. export class UserService {
  10. constructor(private http: Http) {}
  11.  
  12. private usersUrl = 'http://localhost:3000/users';
  13.  
  14. getUsers(): Observable<User[]> {
  15. return this.http.get(this.usersUrl) //the request won't go out until something subscribes to the observable
  16. .map(this.extractData)
  17. .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
  18. }
  19.  
  20. private extractData(response: Response) {
  21. if (response.status < 200 || response.status >= 300) {
  22. throw new Error('Bad response status: ' + response.status);
  23. }
  24. let body = response.json(); // parse JSON string into JavaScript objects
  25.  
  26. return body.data || { };
  27. }
  28.  
  29. private handleError (error: any) {
  30. // In a real world app,we might send the error to remote logging infrastructure before returning/sending the error
  31. let errMsg = error.message || 'Server error'; // transform the error into a user-friendly message
  32.  
  33. return Observable.throw(errMsg); // returns the message in a new,Failed observable
  34. }
  35.  
  36. }

我的组件:

  1. import { Component,OnInit } from '@angular/core';
  2.  
  3. import { User } from '../common/user/user';
  4. import { UserService } from '../common/user/user.service';
  5.  
  6. @Component({
  7. selector: 'app-nav',templateUrl: '/app/nav/nav.component.html',styleUrls: ['/app/nav/nav.component.css']
  8. })
  9. export class NavComponent implements OnInit {
  10. errorMsg: string;
  11. users: User[];
  12.  
  13. constructor(private userService: UserService) { }
  14.  
  15. getUsers() {
  16. this.userService
  17. .getUsers()
  18. .subscribe(
  19. function(users) {
  20. console.log('users ' + users);
  21. this.users = users;
  22. console.log('this.users ' + this.users);
  23. },function(error) {
  24. console.log('error ' + error);
  25. });
  26. // users => this.users = users,// error => this.errorMsg = <any>error);
  27. }
  28.  
  29. ngOnInit() {
  30. this.getUsers();
  31. console.log('ngOnit after getUsers() ' + this.users);
  32. }
  33. }

我的问题是,在getUsers()调用完成后,订阅函数返回的数据没有被传递/分配给我的Component属性’users’.我知道数据是从服务方法调用返回到组件的,因为我能够在userService().getUsers方法中记录数据.奇怪的是,我的ngOnInit上的console.log调用首先在我的开发控制台上打印在我的getUsers方法中的console.logs之前,尽管我首先调用了getUsers:

  1. ngOnInit() {
  2. this.getUsers();
  3. console.log('ngOnit after getUsers() ' + this.users);
  4. }

Dev控制台截图:

这是因为this.getUsers()然后this.userService.getUsers().subscribe(…)仅调度一个调用来向服务器发出请求.最终,当来自服务器的响应到达时(console.log(‘ngOnit在getUsers()’this.users之后);在调用服务器之前已经执行了),然后执行传递给subscribe()的函数.

这应该做你想要的:

  1. getUsers() {
  2. return this.userService
  3. .getUsers()
  4. .map(
  5. (users) => {
  6. console.log('users ' + users);
  7. this.users = users;
  8. console.log('this.users ' + this.users);
  9. })
  10. .catch((error) => {
  11. console.log('error ' + error);
  12. throw error;
  13. });
  14. // users => this.users = users,// error => this.errorMsg = <any>error);
  15. }
  16.  
  17. ngOnInit() {
  18. this.getUsers().subscribe(_ => {;
  19. console.log('ngOnit after getUsers() ' + this.users);
  20. });
  21. }

在getUsers()中,我使用map()而不是subscribe,因此我们可以稍后订阅,以便能够在响应到达时执行代码.

然后在ngOnInit()中我们使用subscribe()(必须使用subscribe(),否则将永远不会执行http.get())并在响应到达时传递我们想要执行的代码.

我还将function()更改为()=>.这种方式适用于以下代码块()=> {…},否则就不会.

别忘了添加

  1. import 'rxjs/add/operator/map';
  2. import 'rxjs/add/operator/catch';

否则这些运算符将无法识别.

猜你在找的Angularjs相关文章