Angular 5-如何在http调用中链接观测值?
我正在用Angular 5编写一个应用程序,我希望在自己的服务中保留原始http调用,以便其他服务可以根据需要操纵响应。 例如,我将有一个组件、组件服务和组件数据服务 我如何将我的观察值与此模式联系起来?以下是我尝试过的: licenseData.service.tsAngular 5-如何在http调用中链接观测值?,angular,typescript,observable,Angular,Typescript,Observable,我正在用Angular 5编写一个应用程序,我希望在自己的服务中保留原始http调用,以便其他服务可以根据需要操纵响应。 例如,我将有一个组件、组件服务和组件数据服务 我如何将我的观察值与此模式联系起来?以下是我尝试过的: licenseData.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpParams, HttpErrorResponse } from '@angular/com
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpErrorResponse } from '@angular/common/http';
import { CONSTANT } from '../../environment/constants';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
@Injectable()
export class LicenseDataService {
constructor(private http: HttpClient) {}
getLicenseInfo() {
const params = new HttpParams()
.set('unsername', 'swapp')
.set('comment', "hi");
const endpoint = '/myendpoint';
return this.http
.get(endpoint, {params: params})
.map((response) => {
console.log(' response ', response);
//return Observable.of<any>(response);
return response['data'];
})
.catch(this.errorHandler);
}
errorHandler(error: HttpErrorResponse) {
//TODO: log the error here
return Observable.throw(error);
}
}
import { Injectable } from '@angular/core';
//import { Observable } from 'rxjs/Observable';
import { LicenseDataService } from './licenseData.service';
@Injectable()
export class LicenseService {
constructor(private licenseDataService: LicenseDataService) { }
getVersion() {
//handle the error in here and the loading as well
return this.licenseDataService.getLicenseInfo()
.subscribe((response) => {
return response['versionNumberField'];
});
//console.log(' result ', result);
//return result['versionNumberField'];
}
}
这是我的部分组件代码:
export class AboutComponent implements OnInit {
//version: Observable<string>;
version: string;
constructor(private licenseService: LicenseService) {
console.log('Hello Component');
}
ngOnInit() {
console.log('ngOnInit');
//this.version = this.licenseService.getVersion();
this.licenseService.getVersion()
.subscribe(response => this.version = response);
}
}
export类AboutComponent实现OnInit{
//版本:可观察;
版本:字符串;
构造函数(专用许可证服务:许可证服务){
log('Hello Component');
}
恩戈尼尼特(){
console.log('ngOnInit');
//this.version=this.licenseService.getVersion();
此.licenseService.getVersion()文件
.subscribe(response=>this.version=response);
}
}
我的项目无法构建。如何正确链接此对象?您无法订阅Subscribtion对象 你有这个密码 许可证数据服务:
return this.licenseDataService.getLicenseInfo()
.subscribe((response) => {
return response['versionNumberField'];
});
在LicenseService中,您尝试订阅LicenseDataService返回的已经是订阅的内容。其中一个选项是在LicenseService中使用map
,然后在组件中订阅
return this.licenseDataService.getLicenseInfo()
.map((response) => {
return response['versionNumberField'];
});
在此之后,您的subscribe
in组件应该可以工作
我个人会使用一种服务,这些操作并没有那么复杂。除非您必须这样做,否则您不希望在服务内部管理订阅 如果我是你,我会将HTTP服务公开为可观察的,并使用共享重播,以便在应用程序的整个生命周期中订阅appVersion时共享结果。这样,您的服务内部就没有内部订阅,这是一种代码气味
@Injectable()
export class LicenseService {
private _appVersion$;
get appVersion$(){
if(!this_appVersion$){
this._appVersion$ = this.getVersion().pipe(shareReplay());
}
return this._appVersion$;
}
private getVersion() {
//handle the error in here and the loading as well
return this.licenseDataService.getLicenseInfo()
.pipe(
map(response => return response['versionNumberField'] as any
);
}
}
然后在您的组件中,您可以注入服务并订阅appVersion$observable以获取应用程序版本值
我之所以这样做,是因为它将一切都保持在一个更具反应性的编程范式中,并允许您将动作与其他异步代码链接在一起。在您的
LicenseService
中,map()
而不是subscribe()
我的最终结果是否需要是一个可观察的值?值没有更新?我不确定您的意思。您能解释更多吗?我如何在代码中使用类似“finally”的内容?文档说finally在Observable上不存在。我用管道尝试了这一点,它给了我以下错误:this.licenseService.getWebwiseVersion()L27:.subscribe((response)=>{console.log(response);this.webwiseVersion=response;});类型“{}”不可分配给类型“Observable”。类型“{}”中缺少属性“\u isScalar”。我进行了几次更新,首先我忘记添加将所有属性绑定在一起的shareReplay操作符,其次我更新了映射,使其将输出强制转换为any,这将修复编译器错误。如果您可以访问属性response.versionNumberField
而不是response['versionNumberField']
,我会这样做,这样它就有了更好的打字支持您想用'finally'做什么?看看angular.io文档。特别是Heros演示应用程序()。您可以看到,我们在组件中订阅,并在服务中执行所有其他操作。根据样式指南,您应该在服务中完成所有的数据操作/映射,所以我将试一试并称之为良好实践。特别是如果您希望使用LicenseService/LicenseDataService。我个人会使用一个服务-这些操作没有那么复杂,我希望有两个服务,因为我将有错误记录和其他事情发生,我不想膨胀我的其他服务。因此,使用这个单独的服务,我认为这是最好的选择。这似乎不是一个坏习惯。您只需在服务中处理数据,然后在组件中获取它们,这样一切都很好。我可以在这里使用什么作为finally块?只需使用rxjs finally块?我不明白你的担心。