2017-02-04 120 views
3

我已经在Angular 2中构建了一个加载spinner组件,我希望在发出http请求之前触发该组件,并在完成时禁用它们。问题在于,每次用户更改输入时(对盒子的检查,输入框中的类型),http请求都会触发。这意味着很多请求,覆盖层不断出现。我想在触发输入之前等待一段时间(半秒?),然后触发http请求,让用户有时间输入其他输入。我已经读了一些关于debounce的内容,但据我所知,这是等待时间再提出另一个请求之前?就我所知,这只是请求之间的缓冲时间。在制作http请求之前限制http请求

基本上,现在,我有一个处理我的输入的组件。当输入改变时(复选框现在),下面的代码被触发:

@Output() filtersChanged = new EventEmitter(); 
emitFilters(): void { 
    this.filtersChanged.emit(this.filters); 
} 

其中通过一个中间步骤,衬托我的http请求:

getEvents(filters): Observable<Event[]> { 
    this.loadingSpinnerService.showLoadingSpinner(); 
    let params: URLSearchParams = new URLSearchParams(); 
    params.set('types', filters.types.join(',')); 
    params.set('dates', filters.dates.join(',')); 
    return this.http 
     .get('//api.dexcon.local/getEvents.php', { search: params }) 
     .map((response: Response) => { 
      return response.json().events; 
     }); 
} 

在角1,我会将其置于每次用户影响输入时刷新的超时,以便在最终输入被触摸后触发设定的时间。这是在Angular 2中完成它的最好方法吗?从我的阅读中,debounce锁定了发出的请求太靠近第二个请求,但我想知道如何最好地防止在给定时间段内采取操作后发生请求。

+0

请发布代码,演示您试图完成的任务,尝试的操作以及失败的位置。 –

+0

我没有特定的限制码,我在询问理论,它应该如何完成。我没有编写代码,因为我无法弄清楚这里适用的方法是什么。我应该从我的Angular 1代码中显示设置的超时功能吗?或者,我应该只是提出我到目前为止使用Angular 2的代码? – RhoVisions

+0

SO问题应该证明你的努力。也许http://stackoverflow.com/questions/32051273/angular2-and-debounce –

回答

3

最简单的方法就是设置一个Subject(我假设你可以访问Rxjs)。初始化一个在你的组件:

inputSubject: Subject<string> = new Subject<string>(); 

由于主题既是观察者和可观察到的,你会想建立一个订阅收听更改。这里是您可以应用去抖动的地方。

this.subscription = this.inputSubject.asObservable() 
    .debounceTime(1000) 
    .subscribe(x => this.filtersChanged.emit(this.filters)); 

现在,在emitFilters()函数,而不是直接发光,推值至被摄体上。

this.inputSubject.next(newValue); 

不要忘记将您的订阅作为组件类的成员存储并在OnDestroy()中正确处理。

ngOnDestroy() { 
    if (this.subscription) { 
     this.subscription.unsubscribe(); 
    } 
} 
+0

@RhoVisions任何想法,这是否会适用于您的方案吗? –

+0

我认为是可观察的,但我不确定,主要是因为我可能不理解去抖动是如何工作的?它是做一个“等待”,还是推动之间的休息?我希望做的事情是,当用户点击一个输入,等待x时间,如果另一个输入被击中,刷新x计时器,如果没有,执行操作。那有意义吗? – RhoVisions

+0

经过测试,虽然我仍然有很多想要了解/了解这一点,但它工作。 – RhoVisions

0

您应该能够通过具有防抖动功能,装饰你的getEvents的方法来解决这个问题:

function debounce(ms: number) { 

     let timeoutId; 

     return function (target: Object, propName: string, descriptor: TypedPropertyDescriptor<any>) { 
      let originalMethod = descriptor.value; 
      descriptor.value = function (...args: any[]) { 
       if (timeoutId) return; 
       timeoutId = window.setTimeout(() => { 
        timeoutId = null; 
       }, ms); 
       return originalMethod.apply(this, args); 
      } 
     } 
    } 

,然后简单地将其应用到你的方法是这样的(设置的装饰参数到你想要去抖时间以毫秒为单位):

@debounce(300) 
getEvents(filters): Observable <Event[]> { 
    ... 
}