以角度2

时间:2016-12-02 14:07:52

标签: angular submit observable subscription

我试图以下列方式使用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)
        }
    });
}

1 个答案:

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