我想从Angular服务提供rxjs Subject
,以便能够通过调用服务上的方法来发出值(通过next
)。我希望它发出的值之一是Angular HttpClient
get
调用的结果。我似乎无法正确解决。我想知道为什么以下结果导致未调用订阅处理程序:
-查看
export default abstract class TileView implements OnInit {
constructor (private configService : ConfigService) {}
ngOnInit () {
this.configService.fetch(this.type()).subscribe( res => {
console.log(res)
});
}
}
-服务
export class ConfigService {
public subject = new AsyncSubject();
constructor (private http : HttpClient) {}
fetch (type) {
this.http.get(
api.host + api.base + interpolate(api.config, { type }) + "/"
).subscribe( res => {
this.subject.next(res);
});
return this.subject;
}
}
是否有任何方法可以返回主题并通过单个方法调用触发http调用?很奇怪,因为返回了主题,注册了订阅者,完成了http调用并调用了this.subject.next(res)
,但是订阅处理程序甚至没有运行。
答案 0 :(得分:1)
Pierre,发生这种情况的原因是, AsyncSubject仅在可观察的完成 (由Subject.prototype.complete()
确定)时才发出最后一个值。
在您的情况下,您可能希望使用BehaviorSubject来为订阅者使用流中的最后一个值,而与完成无关:
AsyncSubject发出最后发出的值(并且仅发出最后一个值) 仅在源可观察到之后 完成。 (如果源Observable没有发出任何值,则 AsyncSubject也会完成而不会发出任何值。)
更新:
如果由于初始值传播而不愿使用BehaviorBehaviorSubject,请使用ReplaySubject(1)。
答案 1 :(得分:1)
完成可观察性,它将起作用
fetch (type) {
this.http.get(
api.host + api.base + interpolate(api.config, { type }) + "/"
).subscribe( res => {
this.subject.next(res);
this.subject.complete();
});
return this.subject;
}
另一种方法是使用BehaviourSubject,在这种情况下,您需要处理空检查,因为BehaviourSubject需要默认值
public behaviourSub = new BehaviorSubject(null);
this.configService.fetch(this.type()).subscribe( res => {
if (res !== null) {
// actual value emitted
}
});
答案 2 :(得分:1)
AsyncObservable的特殊性之一是他在发送信息之前等待“ complete()”完成
由于AsyncSubject扩展了Observable,所以没有必要,但是我建议您使用“ 返回this.subject.asObservable()”,它是“ Subject”对象的一部分。由于您需要在其他类型的主题上使用它,因此,例如,如果通过 BehaviourSubject 更改主题的类型,则无需更改代码;)
答案 3 :(得分:0)
订阅视图中的“主题”以免获取。而且也无需从服务中退还该主题。
视图:
export default abstract class TileView implements OnInit {
constructor (private configService : ConfigService) {}
ngOnInit () {
this.configService.subjectChanged(this.type()).subscribe( res => {
console.log(res)
});
}
}
服务: 导出类ConfigService {
public subjectChanged = new Subject();
constructor (private http : HttpClient) {}
fetch (type) {
this.http.get(
api.host + api.base + interpolate(api.config, { type }) + "/"
).subscribe( res => {
this.subjectChanged.next(res);
});
}
}