2017-09-01 63 views
0

我的目标是在Ionic 3项目中使用RxJs switchMap,以取消任何正在进行的登录尝试(如果服务器脱机并仅使用最新的请求)。否则,我可以在稍后获得一些不需要的异步副作用。尝试使用Ionic 3中的switchMap取消现有的http请求

在我的视图层中,我使用submitStream$来捕获按钮点击流,然后将其作为方法参数传递给服务层。 在服务层中,我通过switchMap创建response$,将传递的参数submitStream$Observable<Response>组合起来,该Observable<Response>this.webServiceUtil.testLogin()返回。

我想实现这个代码:

HTML标记

<button #submit type="submit">Submit</button> 

打字稿:视图层

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/fromEvent'; 
import { ElementRef, ViewChild } from '@angular/core'; 
export class LoginPage { 
    @ViewChild('submit') button: ElementRef 
    submitStream$:any; 
    ... 
    ionViewDidLoad() { 
    this.submitStream$ = 
    Observable.fromEvent(this.button.nativeElement, 'click') 
    } 
    ... 
} 

打字稿:服务层(submitStream $进来的方法参数)

this.response$ = submitStream$.switchMap(click => 
    this.webServiceUtil.testLogin()) 

我也试过在ngAfterViewInit()

创建this.submitStream$当事情没有工作,我也试过这个追加到Observable.fromEvent:

.subscribe(ev => { 
    console.log('LoginPage: ionViewDidLoad() submitStream$.subscribe(): ev:', ev);} 
) 

如何克服'ERROR TypeError: Invalid event target'

+0

为什么使用switchMap()? –

+0

尝试将此代码移动到ngAfterViewInit()函数 –

+0

@SandeepSharma能够取消iniital http请求并接受最新的 – JGFMK

回答

0

看来你必须做一些时髦的东西,让你订阅什么,看在RxJs的眼睛正确...

所以这是我做过什么来解决这个错误类型错误:无效的事件目标:

@ViewChild('submit') button: any; 

    this.submitClickStream$ = 
     Observable.fromEvent(this.button._elementRef.nativeElement , 'click') 
     .subscribe(ev => { 
     console.log('ev: ', ev);}, 
     (err) => {console.error(err);} 
    ); 

AuthService,路过无论是submitClickStream$,或从@ViewChild按钮元素,并从内部AuthService做就可以了Observable.fromEvent,我无法得到与事件控制台记录订阅,以永远火。

所以,我介绍了一个BehaviourSubject中介。

我可以只使用(click)='onSubmit()'中的<button>元素LoginPage.html

LoginPage.ts的onSubmit()方法,我可以直接使用BehaviourSubject与this.clickStream$.next('');

这消除了Observable.fromEvent和ViewChild的复杂性。

switchMap终于开始工作了,取消了之前正在进行的请求而没有混乱的取消订阅逻辑。

LoginPage.ts

import { BehaviorSubject }  from 'rxjs/BehaviorSubject'; 
import { AuthService }   from './../../providers/auth-service'; 
import { LoginCredentials } from './../../model/loginCredentials'; 
export class LoginPage { 

    private clickStream$:BehaviorSubject<any>; 

    constructor(
    private authService:AuthService, 
) { 
    this.clickStream$ = new BehaviorSubject(''); 
    } 

    onSubmit():void { 
    console.log('LoginPage: onSumbit()'); 
    this.clickStream$.next(''); 
    this.authService 
     .login(this.prepareCredentials(), 
      this.clickStream$ 
      ); 
    } 

} 

AuthService

import { BehaviorSubject }  from 'rxjs/BehaviorSubject'; 
import { LoginCredentials }  from './../../model/loginCredentials'; 
import { WebServiceUtil }  from './web-service-util'; 

@Injectable() 
export class AuthService { 

login(
    loginCredentials: LoginCredentials, 
    clickStream$: BehaviorSubject<any> 
) { 
    this.response$ = clickStream$.switchMap(click => { 
         console.log('AuthService: login() : click: ', click); 
         return this.webServiceUtil.testLogin(); 
                 } 
              ); 
    this.response$.subscribe(
     (response:Response) => {....}, 
      (err) => {console.error(err); ....} 

    } 
} 

WebServiceUtil

@Injectable() 
export class WebServiceUtil { 

    testLogin(
): Observable<Response> { 
    ... 
    } 

} 
0

你是版本y关闭。请使用下面给出的开关图。希望这个帮助!

this.submitStream$ = Rx.Observable.fromEvent(this.button._elementRef.nativeElement, 'click'); 

this.submitStream$ 
     .switchMap(click => { 
     return this.dummyAPIResponse(); // this should return observalbe(i.e new observalbe)... 
     }) 
     .subscribe((res) => { 
     console.log(res); 
     }); 


dummyAPIResponse(){ 
return Rx.Observable.create(observer => { 
     setTimeout(() => { 
     observer.next([1, 2, 3, 4]); 
     }, 10000); 
    }); 
}