rxjs可观察的subscirbe模式

时间:2018-01-15 09:14:03

标签: angular rxjs observable reactive-programming

我有以下角度组件,我正在重构使用observable而不是get set和私有成员:

import { Component, OnInit } from '@angular/core';
import { FooService} from './foo.service';

@Component({
    selector: 'app-foo-component',
    templateUrl: './foo-component.component.html',
    styleUrls: ['./foo-component.component.css']
})
export class FooComponent implements OnInit
{
    private _loading: boolean = false;

    public fooForm: FormGroup;    

    public get loading(): boolean
    {
        return this._loading;
    }

    public set loading(
        value: boolean)
    {
        this._loading = value;
        if (value)
        {
            this.fooForm.disable();
        } else
        {
            this.fooForm.enable();
        }
    }

    constructor(
        private fooService: FooService)
    {
    }

    public onSubmitFooForm = () =>
        this.submitFooForm();

    private submitFooForm()
    {
        this.loading = true;

        this.fooService.fooFunction().subscribe((response) =>
        {   
            //navigate or some other custom action on success
            this.loading = false;
        }, () =>
        {
            this.loading = false;
        })
    }

    ngOnInit()
    {
        this.fooForm = new FormGroup();
    }
}

重构组件:

import { Component, OnInit } from '@angular/core';
import { FooService} from './foo.service';
import { Subject } from 'rxjs';

@Component({
        selector: 'app-foo-component',
        templateUrl: './foo-component.component.html',
        styleUrls: ['./foo-component.component.css']
})
export class FooComponent implements OnInit
{
    public fooForm: FormGroup;    

    public loading=new Subject<boolean>();

    constructor(
        private fooService: FooService)
    {
        this.loading.subscribe((isLoading) => this.toggleLoginForm(isLoading));
    }

    public onSubmitFooForm = () =>
        this.submitFooForm();

    private submitFooForm()
    {
        this.toggleLoading(true);   

        this.fooService.fooFunction().subscribe((response) =>
        {   
            //navigate or some other custom action on success
            this.toggleLoading(false);
        }, () =>
        {
            this.toggleLoading(false);
        })
    }

    ngOnInit()
    {
        this.fooForm = new FormGroup();
    }

    private toggleLoading(
        isLoading:boolean): void
    {
        this.loading.next(isLoading);
    }    

    private toggleLoginForm(
        isDisabled:boolean)
    {        
        if(isDisabled) 
        {
            this.fooForm.disable();
        } else 
        {
            this.fooForm.enable();
        }
    }    
}

有没有办法在执行toggleLoading之前和之后自动调用fooService.fooFunction函数,而不是在调用toggleLoading之前和之后手动调用fooService.fooFunction

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题,但是如果只是在一个地方,可以手动完成。

一种方法和首选方法是在构造函数上创建一个新的observable来执行隐式&#39; toggleLoading&#39;在请求之前和之后。我已经添加了可能的解决方案,您可以选择任何您想要的:

import { Component, OnInit } from '@angular/core';
import { FooService} from './foo.service';
import { Subject } from 'rxjs';

@Component({
    selector: 'app-foo-component',
    templateUrl: './foo-component.component.html',
    styleUrls: ['./foo-component.component.css']
})
export class FooComponent implements OnInit
{
public fooForm: FormGroup;    

public loading=new Subject<boolean>();

private fooFunction$: Observable<any>;

constructor(
    private fooService: FooService)
{
    // 1: Observable create approach
    this.fooFunction$ = Observable.create(observer => {
                           this.toggleLoading(true);
                           this.fooService.fooFunction()
                                .finally(() => this.toggleLoading(false))
                                .subcribe(observer)
                       })

    // 2: Observable composition 'trick' approach
    this.fooFunction$ = Observable.empty()
                         .do(() => this.toggleLoading(true))
                         .concat(
                               this.fooService.fooFunction()
                               .finally(() => this.toggleLoading(false))
                         )

    this.loading.subscribe((isLoading) => this.toggleLoginForm(isLoading));
}

public onSubmitFooForm = () =>
    this.submitFooForm();

private submitFooForm()
{ 
    this.fooFunction$.subscribe((response) =>
    {   
        //Do whatever on success
    }, () =>
    {
        // Do whatever on error
    })
}

ngOnInit()
{
    this.fooForm = new FormGroup();
}

private toggleLoading(
    isLoading:boolean): void
{
    this.loading.next(isLoading);
}    

private toggleLoginForm(
    isDisabled:boolean)
{        
    if(isDisabled) 
    {
        this.fooForm.disable();
    } else 
    {
        this.fooForm.enable();
    }
}    
}

希望这有帮助。