简体   繁体   English

为什么在Angular2的反跳期之后没有调用我的搜索方法

[英]Why doesn't my search method get called after the debounce period in Angular2

I'm plaguarizing the angular2 heroes tutorial code to learn more. 我毁了angular2英雄教程代码,以了解更多信息。 I have this search component in it's own search directory. 我在自己的搜索目录中有此搜索组件。 There is a PersonSearchService which will be called in the same directory. 有一个PersonSearchService,它将在同一目录中调用。 My search method is getting called each time a key is pressed in my input field. 每次在输入字段中按下一个键时,都会调用我的搜索方法。 However the code in the ngOnInit() does not get invoked each time searchTerms changes. 但是,每次searchTerms更改时,不会调用ngOnInit()中的代码。 I have set a breakpoint in my PersonSearchService and in the switchmap and neither are getting hit. 我已经在PersonSearchService和switchmap中设置了一个断点,但都没有命中。 Do you have any ideas on why that might happen. 您对可能发生这种情况有任何想法吗?

import { Component, OnInit } from '@angular/core';  
import { Router }            from '@angular/router';

import {Observable}          from 'rxjs/Observable';
import { Subject }           from 'rxjs';
import {PersonSearchService} from './person-search.service';
import {Person} from '../person';

@Component({
  selector: 'person-search',
  templateUrl: './person-search.component.html',
  styleUrls: ['./person-search.component.css'],
  providers: [PersonSearchService]
})

export class PersonSearchComponent implements OnInit {
  persons: Observable<Person[]>;
  private searchTerms = new Subject<string>();

  constructor(
    private personSearchService: PersonSearchService) {}

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term);
  }

  ngOnInit() {
    this.persons = this.searchTerms
      .debounceTime(300)        // wait for 300ms pause in events
      .distinctUntilChanged()   // ignore if next search term is same as prev
      .switchMap(term => term   // switch to new observable each time
        // return the http search observable
        ? this.personSearchService.search(term)
        // or the observable of empty heroes if no search term
        : Observable.of<Person[]>([]))
      .catch(error => {
        // TODO: real error handling
        console.log(error);
        return Observable.of<Person[]>([]);
      });
      }
    }

It's a very common misunderstanding of how Observables work. 这是对“可观察物”如何工作的一个非常普遍的误解。

What you have assigned to the this.persons is a declaration of what you want to do. 您分配给this.persons是对您要执行的操作的声明 This is observable and not the result you want to get. 这是可以观察到的,而不是您想要获得的结果。 This thing will not do anything by itself. 这个东西本身不会做任何事情。 To kick it out you need to subscribe to this declaration, and only then you will get the results you want into your subscription. 要踢出去,您需要订阅此声明,然后您才能在订阅中得到想要的结果。 So corrected version of you component would be something like this: 因此,您的组件的更正版本将如下所示:

import { Component, OnInit, OnDestroy } from '@angular/core';  
import { Router }            from '@angular/router';

import {Observable}          from 'rxjs/Observable';
import { Subject }           from 'rxjs';
import {PersonSearchService} from './person-search.service';
import {Person} from '../person';

@Component({
  selector: 'person-search',
  templateUrl: './person-search.component.html',
  styleUrls: ['./person-search.component.css'],
  providers: [PersonSearchService]
})

export class PersonSearchComponent implements OnInit, OnDestroy {
  persons: Person[]; // see here? it's not an observable
  private searchTerms = new Subject<string>();
  private subscription: Subscription; // todo: add to imports from Rx

  constructor(
    private personSearchService: PersonSearchService) {}

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term);
  }

  ngOnInit() {
    this.subscription = 
        this.searchTerms
          .debounceTime(300)        // wait for 300ms pause in events
          .distinctUntilChanged()   // ignore if next search term is same as prev
          .switchMap(term => term   // switch to new observable each time
            // return the http search observable
            ? this.personSearchService.search(term)
            // or the observable of empty heroes if no search term
            : Observable.of<Person[]>([]))
          .catch(error => {
            // TODO: real error handling
            console.log(error);
            return Observable.of<Person[]>([]);
          })
          .subscribe((result: Person[]) => {
            this.persons = result;
          });
    }

    ngOnDestroy() {
        // and don't forget cleanup
        this.subscription.unsubscribe();
    }

}

The search method will be invoked each time you press a key, because you attached to on keyup event in the search.component.html 每次您按下一个键都会调用搜索方法,因为您已附加到search.component.html中的on keyup事件。

<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />

but the code on the ngOnInit method, more specifically, the switchMap method is invoked after 300 miliseconds if, only if, the value of the input changed. 但是ngOnInit方法上的代码,更具体地说,如果输入值发生变化,则300毫秒后将调用switchMap方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM