繁体   English   中英

角度2+承诺,可观察和异步管道

[英]angular 2+ Promises, Observable and async pipe

我正在第一个用angular 4进行的项目中遇到一个小问题。

当我调用服务器时,会有一个延迟,并且我学会了使用异步管道来显示我从服务器获取的数据。

但是我遇到的问题是,例如,我对服务器进行了HTTP调用,现在我正在等待信息从服务器返回。 但是我需要这些信息来做一些数字运算。 因此,我分配的等待服务器信息的变量将以未定义的形式返回,因为在运行时代码已执行并且没有可分配的值。

ngOnInit(){
    this.settings = this.settingsService.getSettings();
    console.log("Logging Settings: " + this.settings);  // ends up being undefined
  }

onDoSomething(){
    return this.settings * gazillion;  // doesn't work 
}

进行服务调用并让方法DoSomething知道推迟进行直到获得设置的正确方法是什么? 另外,如果您在整个应用程序中使用设置,那么将如何存储它,这样就不会在每次需要设置时都不断进行HTTP调用。

我的直觉是让app.componenet.ts进行呼叫并存储。

谢谢!

通常以角度2的返回观测值服务。 这是因为http请求花费可变的时间来返回服务器中的数据。

我不确定getsettings到底在做什么,但是一般的设置如下:

//service layer
    function getSettings() {
        return this.http.get(`server-url`)
            .map((response: Response) => <any>response.json())
            .catch(this.handleError);
}

private handleError(error: Response) {
    return Observable.throw(error.json() || 'Server error');
}
//in your component
this.service.getSettings().subscribe(result => {this.settings = result}, error => {console.log("there was an error.")});

http请求响应客户端后,将触发订阅部分。

在此过程中有几件事可以帮助您:

  • 如果数据准备好直接从服务器提供服务,那么异步管道非常有用。 如果您在组件中需要它,请不要使用异步管道,而只需订阅即可。
  • Angular会从http请求中返回可观察到的内容,然后您可以使用subcribe()函数,并提供想要在检索到数据或失败后执行的操作。

这是有关在角度服务中使用http的很好的教程

在您的特定情况下,您需要这样的东西:

ngOnInit(){
    this.settings = this.settingsService.getSettings().subscribe((settings)=>{
    this.settings = settings;
    console.log("Logging Settings: " + this.settings);
}

为了回答您的第二个问题,Angular服务(如果按开发人员的意图完成)遵循Singleton模式,并且是整个应用程序中的共享资源。 这意味着访问它的所有对象都接收与其他对象相同的实例。

对于do或map运算符,这是一个完美的用例,具体取决于您要实际实现的目标:

this.settings = this.settingsService.getSettings().do(settings => this.doSomething(settings));

如果您只是想要一个“副作用”,例如您实际上不希望影响发送显示器的数据,则只想对它进行其他与显示无关的操作,但是您需要在发生这种情况的同时进行序列中的特定点(我经常会使用do()来隐藏整个页面范围的内容加载弹出窗口或其他内容)。 doSomething()是否返回值并不重要,因为它将不被使用。

this.settings = this.settingsService.getSettings().map(settings => this.transformSettings(settings));

如果您想实际更改要发送到显示器的数据,则在这种情况下会大量使用map运算符。 transformSettings()必须返回一个值,该值是您要特别显示的值,因为它将被传递给最终订阅者。

对于第2部分,将结果存储在服务层上的行为主题中,以便对需要它的任何组件始终可用:

private settingsSource = new BehaviorSubject(null);
settings$ = this.settingsSource.asObservable().filter(e => !!e); //this prevents the initial null value from being sent
loadSettings() {
    this.http.get('settings').map(r => r.json()).subscribe(this.settingsSource);
}
constructor(private http: HttpClient) {
  this.loadSettings();
}

然后让您的组件订阅settings $,只要到达那里,它就会在那里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM