在角度 2 中订阅关于数据提交的可观察对象

Subsribing to an observable on data submission in angular2

我正在尝试通过以下方式使用 Observable/Behaviour 主题: 我有一个组件作为背景显示在应用程序的任何地方。 在显示我想要的背景的表单组件中 获取来自用户的数据和 使用此数据进行异步调用,并使用该异步调用的结果调用该后台组件中的方法
所以在我的 app.component.ts 我有

<app-header></app-header>
 <backround-component></background-component>
 <router-outlet></router-outlet>

ln 在我的 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 }, 
];

形式-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 生命周期挂钩中订阅后台组件中的可观察对象,以便我可以使用响应:

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)
        }
    });
}

嘿,我向您展示了如何通过创建可观察服务在多个组件之间共享数据的示例:

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);
    }
}