等待订阅void方法

时间:2018-04-13 17:18:52

标签: angular rxjs

我对rxjs相当新,我在观察能力方面遇到了麻烦。

在导航到下一页之前,我需要验证总数是否未发生变化,通常在添加项目时会异步调用calculateTotal方法。 但在继续下一页之前,我想确保当前的交易总数是正确的。

这不完全是代码,但或多或​​少代表了我想要做的事情。

public navigateToNextStep() {
    if (isTransactionValid()) {
        this.router.navigate([CodeClient.RoutingToDetailsPage]);
    }
}
private isTransactionValid() {
    let total = this.transaction.Total;

    this.calculateTotal(); //need to wait for this to finish

    if (total == this.transaction.Total) {
        return true;
    }
    return false;
}

问题是我需要找到一种方法来完成calculateTotal()的完成,然后再进行下一步。

private calculateTotal() {
    this.transactionService.calculateTotal(this.transaction).subscribe(
        (result) => {
            this.transaction.Total = result.Total;
            }
    );
}

transactionService

public calculateTotal(trans: Trans): Observable<TotalResult> {
    return this.http.post<TotalResult>(this.api_url, Trans);
}

谢谢。

2 个答案:

答案 0 :(得分:1)

检查订阅方法中的条件。

public navigateToNextStep() {
    let total = this.transaction.Total;
    this.transactionService.calculateTotal(this.transaction).subscribe(
        (result) => {
            this.transaction.Total = result.Total;
            if (total == this.transaction.Total) {
                this.router.navigate([CodeClient.RoutingToDetailsPage]);
            }

        }
    );
}

答案 1 :(得分:1)

你好@Daniel你的行为非常接近promise approch,你可以做这样的事情,不是最干净的方法,只是简单的样本向你展示如何处理完全自制的Observable。 / p>

import { Component, OnInit} from '@angular/core';
import { Observable } from 'rxjs/Observable';
import {Subscriber} from 'rxjs/Subscriber';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: [ './app.component.css' ]
})
export class AppComponent  implements OnInit {

    obs: Subscriber<number>;
    calculate$: Observable<number>;

    price: number = null;
    quantity: number = null;

    ngOnInit() {
        //We craft home made observable.
        this.calculate$ = Observable.create((obs) => {
            //We keep reference of Observer as attribut of class.
            this.obs = obs; 
            //We init first value as null.
            this.obs.next(null);    
        });  
    }

    private validate() {
        //We assume we consider as valid, any value differente than null.
        if (this.price !== null && this.quantity !== null) 
        {
            //We next new data.
            this.obs.next(this.price * this.quantity);
            //We complete this observable because we don't need it anymore.
            this.obs.complete();
        }
    }

    onPriceHandler() 
    {
        // Possible case of validation.
        this.validate();
    }

    onQuantityHandler() 
    {
        // Possible case of validation.
        this.validate();
    }
}

Html方面:

<p>Price :</p>
<input type="number" name="price" [(ngModel)]="price" (change)="onPriceHandler()">
<br>
<p>Quantity :</p>
<input type="number" name="quantity" [(ngModel)]="quantity" (change)="onQuantityHandler()">
<br>
<!-- We don't display "go to next step" button until we have not validate -->
<button *ngIf="(calculate$ | async) !== null"> go next step</button>

Live sample

_编辑1 _

就我而言,最好使用BehaviorSubject,必须进行小更新:

price: number = null;
quantity: number = null;
isValid$ : BehaviorSubject<boolean>;

ngOnInit() {
    // We init our observable by false, by default is not valid.
    this.isValid$ = new BehaviorSubject(false);
}

private validate() {
    //We assume we consider as valid, any value differente than null.
    if (this.price !== null && this.quantity !== null) 
    {
        //We next new data.
        this.isValid$.next(true);
        //We complete this observable because we don't need it anymore.
        this.isValid$.complete();
    }
}

Html方面:      下一步

Live sample