我试图以下列方式使用Observable / Behavior主题: 我有一个组件,它在应用程序中随处显示为背景。 在一个表单组件中显示我想要的背景 获取来自用户的数据 使用此数据进行异步调用,并使用该异步调用的结果在该后台组件中使用该方法 所以在我的app.component.ts中我有
<app-header></app-header>
<backround-component></background-component>
<router-outlet></router-outlet>
在我的app.routing.ts中,我有:
const appRoutes: Routes = [
{ path: '',
redirectTo: 'home',
pathMatch: 'full'},
{ path: 'home', component: HomeComponent },
{ path: 'form-component', component: Form component where the user submits the data },
];
在form-component.html中我有:
<button class="btn--submit" (click)="onClick()">Click</button>
所以我想做的是:
1)在表单组件中提交数据时,请根据提交的数据调用构建请求的服务中的方法:
onClick = function() {
this.service.makeAsynchCall(dataFromTheUser);
}
2)异步调用远程API:
public makeAsynchCall(dataFromTheUser): Observable<any> {
// build the request based on the data
return Observable.create((observer) => {
this.someRemoteService.route(request, (response, status) => {
observer.next(response);
});
});
}
3)在ngBeforeView生命周期钩子中的后台组件中订阅该observable,以便我可以使用响应:
ngBeforeView {
this.service.makeAsynchcall().subscribe(response =>
this.useTheResponse(response);
);
}
我认为正在发生的是,在加载该后台组件时,首先强制调用异步调用,然后强制调用期望来自用户的数据的方法,数据尚未提交,请求失败。 我还尝试了另一种方案 - 使用BehaviourSubject / AsyncSubject作为连接件,利用其观察者和Observable的角色,并在数据到达时通知其他订阅者并且也不起作用。 提前感谢您的帮助。
更新:根据以下答案中的示例尝试了以下内容
这是我试图做的。在我的订阅者中,next()方法只打印接收的值。其他一切都是一样的(除了我没有创建数据模型)
public update(data)
{
let request = {}; // build request object based on 'data'
this.source.next(data); // subscriber doesn't get the value (not printed)
// make async call
this.service.asyncCall(request, (response, status) => {
if (status == OK) {
console.log('got result'); // this prints, so we get here
this.source.next(data); // subscriber doesn't get the value (not printed)
}
});
}
答案 0 :(得分:2)
嘿,我通过制作可观察的服务,让你成为如何在多个组件之间共享数据的例子:
import {ReplaySubject, Subscription} from "rxjs";
export class DataModel
{
constructor(public valueOne: string,
public valueTwo: string)
{
}
}
export class FormComponent
{
constructor(private shareService: ShareService)
{
}
onFormSubmit(formData: DataModel)
{
const newData = new DataModel(formData.valueOne, formData.valueTwo)
this.shareService.update(newData);
}
}
export class ShareService
{
private source = new ReplaySubject<DataModel>();
public source$ = this.source.asObservable();
public update(data)
{
this.source.next(data)
}
}
export class BackGroundComponet
{
private subscription: Subscription;
private data: DataModel;
constructor(private shareService: ShareService)
{
this.subscription = this.shareService
.source$
.subscribe(data =>
{
this.data = data; //assign new data to class member
this.onShareServiceUpdated(); //call some method to do something with it
});
}
private onShareServiceUpdated()
{
//Make api call with new data
console.log(this.data);
}
}