我正在尝试使用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);
}
开发者控制台截图:
答案 0 :(得分:8)
这是因为this.getUsers()
然后this.userService.getUsers().subscribe(...)
仅调度向服务器发出请求的调用。最终,当服务器的响应到达时(console.log('ngOnit after getUsers() ' + this.users);
已在执行服务器调用之前执行),然后执行传递给subscribe()
的函数。
这应该做你想要的:
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()
而不是订阅,因此我们可以稍后订阅,以便能够在响应到达时执行代码。
然后在ngOnInit()
我们使用subscribe()
(subscribe()
是必要的,否则http.get()
永远不会被执行)并传递我们想要执行的代码回应到了。
我还将function ()
更改为() =>
。这种方式this
适用于以下代码块() => { ... }
,否则就不会。
别忘了添加
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
否则这些操作员不会被识别出来。
答案 1 :(得分:0)
对我来说,这就像魔术一样 我需要从api获取数据以初始化datatable组件
1-在您的http服务上创建正常的get请求,如下所示:
public get(url: string):Observable<any> {
return this.http.get<any>( url );
}
2-在您的组件上:
constructor(private HttpSvc: HttpService) {}
ngOnInit() {
this.render();
}
render() {
let options = this.options || {};
this.HttpSvc.Get('your api url').subscribe(data => {
this.Tableset = data;
options = {
data: this.Tableset.data,
columns: this.Tableset.columns,
dom: 'Bfrtip',
buttons: this.Tableset.buttons,
autoWidth: false,
pageLength: 2,
retrieve: true,
responsive: true
};
}, err => {console.log(err); },
() => {
this.renderDetails(options); //<-- can call any other method after call end
});
}
此处是完整示例link