【发布时间】:2017-11-18 07:59:00
【问题描述】:
我的服务代码如下所示 -
数据服务
@Injectable()
export class DataService {
...
private serviceRequestDtoSource = new BehaviorSubject<ServiceRequestDto>(null);
serviceRequestDto$ = this.serviceRequestDtoSource.asObservable();
...
getAccountInfo(serviceRequestDto : ServiceRequestDto){
let body = JSON.stringify(serviceRequestDto);
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({ headers: headers });
console.log("In data service.getAccountInfo");
this.http
.post(this.clientAccountInfoURL, body, options)
.map((response : Response) => { return <AccountDto[]> response.json().accountDtoList})
.do(data=> console.log('All :'+ JSON.stringify(data)))
.subscribe( response => {
this.accountList = response;
this.serviceRequestDto.accountDtoList = this.accountList;
this.serviceRequestDtoSource.next(serviceRequestDto);
},
error => this.errorMessage = <any>error);
}
搜索组件(点击上述服务并订阅)如下所示 -
onSearch(value) {
...
this.dataService.getAccountInfo(this.serviceRequestDto); //service call
this.subscription = this.dataService.serviceRequestDto$
.subscribe( (serviceRequestDtoValue : ServiceRequestDto) => {
// Control doesn't come here..
this.serviceRequestDto = serviceRequestDtoValue;
console.log('search.serviceRequestDto.length:'+this.serviceRequestDto.accountDtoList.length);
console.log('search.serviceRequestDto.accountDtoList.name:'+this.serviceRequestDto.accountDtoList[0].name);
});
如上所述,在观察组件的 subscribe 方法中没有控制权,因为没有打印任何日志,而且我在控制台中也没有收到任何错误。不确定我是否以正确的方式使用 BehaviorSubject。
我尝试关注以下链接 -
Angular 2 - Behavior Subject vs Observable? -> 没有像这里提到的那样进入订阅。
http-observables -> 当我尝试这种方式时,它确实进入了订阅,但随后引发了日志错误 -
无法读取 null 的属性 xyz 因为组件日志甚至在我从服务获取数据之前就被打印出来了。服务日志在我得到上述错误之后被打印出来。
我的意图不是从 SearchComponent 本身订阅服务的 BehaviorSubject。我只是想测试我是否从 any 组件中的服务中获取值。我相信它与订阅任何其他需要 serviceRequestDto 值作为订阅语法在所有组件中保持不变。
更新 1:
我尝试按照 Brandon 的建议使用 ReplaySubject(1),但在订阅组件中的主题时我仍然遇到错误。
TypeError: 无法读取 undefined(...) 的属性“名称”
我更新后的 service 代码现在看起来像这样 -
serviceRequestDtoSource = new ReplaySubject<ServiceRequestDto>(1);
getAccountInfo(serviceRequestDto : ServiceRequestDto){
...
//Logic same as earlier
//I'm getting all values from service here in the logs I print
}
请注意我之前在 service 代码中使用了以下代码 -
private serviceRequestDtoSource = new BehaviorSubject<ServiceRequestDto>(null);
serviceRequestDto$ = this.serviceRequestDtoSource.asObservable();
我更新的 搜索组件 代码如下所示 -
this.dataService.getAccountInfo(this.serviceRequestDto);
this.dataService.serviceRequestDtoSource.subscribe((serviceRequestDtoValue : ServiceRequestDto) => {
this.serviceRequestDto = serviceRequestDtoValue;
console.log('search.serviceRequestDto.length:'+this.serviceRequestDto.accountDtoList.length);
// prints 'search.serviceRequestDto.length:0'
console.log('search.serviceRequestDto.accountDtoList name:'+this.serviceRequestDto.accountDtoList[0].name); // throws 'vendor.bundle.js:5764 ERROR TypeError: Cannot read property 'name' of undefined(…)' error
});
早期组件代码订阅主题的方式不同,尽管没有错误,但控件从未进入组件的订阅内。
我的初始代码与我现在发布的不同,它基于以下链接 - delegation-eventemitter-or-observable-in-angular2
【问题讨论】:
标签: angular rxjs behaviorsubject