2017-11-17 1 views
2

Ich bin sehr neu in Typoskript. Ich versuche die Observablen zu verstehen, aber ich bin hier irgendwie verloren. Die folgende Funktion sucht nach Videos auf Youtube API v3. Ist es ein guter Ansatz? Ist das Abonnieren innerhalb einer Funktion, die oft eine gute Idee genannt wird? Diese Funktion wird aufgerufen, wenn der Benutzer etwas eingibt.Wie und wann zu abonnieren?

Sollte ich irgendwo eine unsubscribe haben?

searchVideos(searchbar: any): void{ 
    const typedValue: string = searchbar.srcElement.value; 

    if(typedValue.length > 2){ 
    this.videosList = this.youtubeProvider.searchVideos(typedValue); 
    this.videosList.subscribe(data => { 
     if(data.length == 0 ){ 
     this.notFoundAnyVideo = true; 
     }else{ 
     this.notFoundAnyVideo = false; 
     } 
    }) 
    } 
} 

Antwort

0

Es ist eine gute Frage!

Sie sind einige Möglichkeiten, um Ihre Frage zu beantworten:

1/können Sie die Aktion Entprellen, die Ihre Funktion aufrufen

Stellen Sie sich vor, Ihre Aktion wird von einem keyup in Eingabefeld ausgelöst:

HTML

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

Komponente

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/können Sie die beobachtbaren mit takeUntil

Komponente

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; } 
      }) 
     } 
    } 

} 

Natürlich stornieren Sie 1 kombinieren und 2

Warum ich takeUntil verwenden meine Anfragen stornieren : https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87

+0

was ist, wenn ich .first() .subscribe() verwende? – adsfelipe

+0

Wenn Sie den Operator verwenden. Zuerst nehmen Sie das erste Element der beobachtbaren: https://www.learnrxjs.io/operators/filtering/first.html Also, wenn Sie mehr als ein Video von Ihrem Anruf haben, Sie einfach immer siehe die erste und nie die anderen – mickaelw

0

Ich nehme an, Sie könnten RxJS verwenden, weil sein reaktives Paradigma sehr gut für Suchkomponenten geeignet ist. Sehen Sie sich den folgenden Code an, ich habe Variationen davon in wenigen Anwendungen implementiert.

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(); 
     } 
    } 
+0

Was ist, wenn ich .first() .subscribe() verwende? – adsfelipe

+0

Das ist, was mickaelw gesagt hat -> '.first()', '.last()' und '.take (2)' funktionieren auf die gleiche Weise, sie sind Filteroperatoren, die nur einen Wert (oder mehr, wenn Sie verwenden) 'nimm'). Sie möchten das nicht tun, wenn Sie alle vorgeschlagenen Videos anzeigen möchten, nicht nur eines. Es sei denn, Ihre Suche dient einem anderen Zweck als den üblichen Suchen. – codeepic

Verwandte Themen