Angular2-OnInit:从服务返回的值';订阅功能未分配给组件字段

Angular2-OnInit:从服务返回的值';订阅功能未分配给组件字段,angular,Angular,我正在尝试Angular2,并且一直在关注他们的教程 我目前有一个从json服务器获取数据的服务: 从'@angular/core'导入{Injectable}; 从'@angular/Http'导入{Http,Response}; 从“rxjs/Observable”导入{Observable}; 从“/User”导入{User}; @可注射() 导出类用户服务{ 构造函数(私有http:http){} 私有用户http://localhost:3000/users'; getUsers():

我正在尝试Angular2,并且一直在关注他们的教程

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

从'@angular/core'导入{Injectable};
从'@angular/Http'导入{Http,Response};
从“rxjs/Observable”导入{Observable};
从“/User”导入{User};
@可注射()
导出类用户服务{
构造函数(私有http:http){}
私有用户http://localhost:3000/users';
getUsers():可观察{
返回this.http.get(this.usersUrl)//直到有东西订阅了可观察对象,请求才会发出
.map(此.extractData)
.catch(this.handleError);//将错误消息传递回组件,以便向用户演示,但前提是我们能够说出用户能够理解和执行的内容
}
私有数据(响应:响应){
如果(response.status<200 | | response.status>=300){
抛出新错误(“错误响应状态:”+响应状态);
}
let body=response.json();//将json字符串解析为JavaScript对象
返回body.data |{};
}
私有句柄错误(错误:任意){
//在现实世界的应用程序中,我们可能会在返回/发送错误之前将错误发送到远程日志记录基础设施
让errMsg=error.message | |“服务器错误”;//将错误转换为用户友好的消息
return Observable.throw(errMsg);//以新的、失败的Observable返回消息
}
}
和我的组件:

从'@angular/core'导入{Component,OnInit};
从“../common/User/User”导入{User};
从“../common/user/user.service”导入{UserService};
@组成部分({
选择器:“应用导航”,
templateUrl:“/app/nav/nav.component.html”,
样式URL:['/app/nav/nav.component.css']
})
导出类NavComponent实现OnInit{
errorMsg:string;
用户:用户[];
构造函数(私有用户服务:用户服务){}
getUsers(){
这个是.userService
.getUsers()
.订阅(
功能(用户){
console.log('用户'+用户);
this.users=用户;
console.log('this.users'+this.users);
},函数(错误){
console.log('error'+error);
});
//users=>this.users=users,
//error=>this.errorMsg=error);
}
恩戈尼尼特(){
这是getUsers();
log('getUsers()之后的ngOnit'+this.users);
}
}
我的问题是,在getUsers()调用完成后,从订阅函数返回的数据没有传递/分配给我的组件属性“users”。我知道数据是从服务方法调用返回到组件的,因为我能够在userService().getUsers方法中记录数据。奇怪的是,ngOnInit上的console.log调用首先打印在我的开发控制台上,然后打印在getUsers方法中的console.log上,尽管我先调用getUsers:

ngOnInit(){
这是getUsers();
log('getUsers()之后的ngOnit'+this.users);
}
开发人员控制台屏幕截图:


这是因为
This.getUsers()
然后
This.userService.getUsers().subscribe(…)
只安排一个调用向服务器发出请求。最终,当来自服务器的响应到达(
console.log('ngOnit after getUsers()'+this.users);
在调用服务器之前就已经执行了),然后执行传递给
subscribe()
的函数

这应该满足您的要求:

getUsers(){
返回此.userService
.getUsers()
.地图(
(用户)=>{
console.log('用户'+用户);
this.users=用户;
console.log('this.users'+this.users);
})
.catch((错误)=>{
console.log('error'+error);
投掷误差;
});
//users=>this.users=users,
//error=>this.errorMsg=error);
}
恩戈尼尼特(){
this.getUsers().subscribe(=>{;
log('getUsers()之后的ngOnit'+this.users);
});
}
getUsers()
中,我使用
map()
而不是subscribe,因此我们可以稍后订阅,以便能够在响应到达时执行代码

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

我还将
函数()
更改为
()=>
。这样
这个
在下面的代码块
()=>{…}
中工作,否则它就不会工作

别忘了加上

导入'rxjs/add/operator/map';
导入“rxjs/add/operator/catch”;

否则这些操作符将不会被重新编码。

对我来说,这就像魔术一样有效 我需要从api获取数据来初始化datatable组件

1-在http服务上创建如下的正常get请求:

  public get(url: string):Observable<any> {
    return this.http.get<any>( url );
   }

public get(url:string):可观察的

谢谢您的回答,先生,在尝试之后,该值确实会在ngOnInit控制台日志调用中打印出来,但是当我在模板中引用users属性时,仍然会得到一个未定义的值。不过,使用异步特性作为隐式订阅从服务get方法调用返回的可观察对象的替代方案是可行的。我仍然不明白为什么上面的内容在Angular的教程中起作用时不起作用?这个错误是Angular试图在
ngOnInit()
之前绑定值造成的。只需使用
{{users?.xxx}}
而不是
{{users.xxx}}
就不会得到错误。这解决了我的问题,先生。谢谢很高兴听到:)它被称为安全导航或猫王操作员,以防你想查找它。写上一条评论时我正在打电话,因此我保持简短
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
          });
    }