如何以及何时使用订阅?

时间:2017-11-17 14:21:43

标签: rxjs ionic3

我是打字稿的新手。 我正在努力了解Observables,但我有点迷失在这里。 以下功能在Youtube API v3上搜索视频。 这是一个好方法吗? 订阅内部函数会被多次调用好主意吗? 只要用户输入内容,就会调用此函数。

我应该在某处// trigger an error, but nicely, if need be protected function _raiseFormulaError($errorMessage) { $this->formulaError = $errorMessage; $this->_cyclicReferenceStack->clear(); 3734 if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); trigger_error($errorMessage, E_USER_ERROR); } // function _raiseFormulaError() 吗?

unsubscribe

2 个答案:

答案 0 :(得分:0)

这是一个很好的问题!

他们是回答你问题的一些方法:

1 /你可以去除调用你的功能的动作

想象一下,您的操作是由输入字段中的键盘触发的:

<强> HTML

<input type="text" (keyup)="onSearchKeyup(this.value, $event)">

<强>组件

export class MyComponent implements OnInt {

   onSearch$: Subject<string>

   ngOnInt(): void {
      this.onSearch$
          .debounceTime(500) //-> put your time here
          .subscribe(search => searchVideos(search)
   }

   onSearchKeyup(search: string, e: any) {
      this.onSearch$.next(search)
      e.preventDefault()
   }

}

2 /你可以用takeUntil

取消observable

<强>组件

export class MyComponent implements OnInt {

   onStopSearch$: Subject<void> = new Subject<void>();

   onSearchKeyup(search: string, e: any) {
      this.onStopSearch$.next()
      this.searchVideos(string)
      e.preventDefault()
   }

   private searchVideos(search: string): void{
      if(typedValue.length > 2){
         this.videosList = this.youtubeProvider.searchVideos(typedValue);
         this.videosList
             .takeUntil(this.onSearchStop$)
             .subscribe(data => {
                if( data.length == 0  ){
                   this.notFoundAnyVideo = true;
                }else{ this.notFoundAnyVideo = false; }
             })
      }
   }

}

当然你可以结合1和2

为什么我使用takeUntil来取消我的请求:https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87

答案 1 :(得分:0)

我想你可以一直使用RxJS,因为它的反应范式非常适合搜索组件。看看下面的代码,我在很少的应用程序中实现了它的变体。

import {Component, ViewChild, ElementRef} from "@angular/core";

@Component({        
      selector: 'search',        
      styleUrls: ['./search.component.scss'],    
      template: `    
        <form #searchBoxEl action="" class="search-form" [formGroup]="form">
          <fieldset>
            <input #searchBoxEl type="text" placeholder='Search for Youtube videos'
            autocomplete="off" />

            <nwum-list (itemSelected)="onItemSelect($event)"></nwum-list>

          </fieldset>
        </form>
      `,
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class SearchComponent implements OnInit {
        @ViewChild('searchBoxEl') searchBoxEl: ElementRef;
        componentDestroyed$: Subject<void> = new Subject<void>();
        videosList: Video[];

      constructor(public videoService: VideoService){}


        ngOnInit(){
          subscribeToSearchQueryChanges();     
        }

        subscribeToSearchQueryChanges(){
            const minNumOfChars = 2;

            Observable.fromEvent(this.searchBoxEl.nativeElement, 'keyup')
                .debounceTime(300)
                .pluck('target', 'value')
                .map(value => value.trim())
                // .map(() => this.searchBoxEl.nativeElement.value.trim())
                .filter(value => value.length >= minNumOfChars)
                .takeUntil(this.componentDestroyed$)
                .switchMap(value => this.videoService.fetchVideos(value))
                .subscribe((videos: Video[]) => {
                    //show videos, etc
                    this.videosList = this.videoService.groupSuggestions(suggestions);
                }, err => {
                    console.error('failed fetching videos', err);
                    this.removeAllSubscriptions();
                    this.subscribeToSearchQueryChanges();
                });

            this.addSubscription(sub);
        }


        ngOnDestroy() {
          this.removeAllSubscriptions();      
        }

        removeAllSubscriptions(){
            this.componentDestroyed$.next();
            this.componentDestroyed$.complete();
        }
    }