为什么我的搜索方法在Angular2

时间:2016-12-02 02:41:45

标签: angular search rxjs

我正在游荡angular2英雄教程代码以了解更多信息。我在它自己的搜索目录中有这个搜索组件。有一个PersonSearchService将在同一目录中调用。每次在输入字段中按下某个键时,都会调用我的搜索方法。但是,每次searchTerms更改时都不会调用ngOnInit()中的代码。我在PersonSearchService和switchmap中设置了一个断点,但都没有被击中。您对可能发生的原因有任何想法吗?

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[]>([]);
      });
      }
    }

2 个答案:

答案 0 :(得分:0)

这是对Observables如何运作的一种非常普遍的误解。

您分配给this.persons的内容是声明您想要做的事情。这是可观察的,而不是你想得到的结果。这件事本身不会做任何事情。要启动它,您需要订阅到此声明,只有这样您才能获得所需的结果。因此,您组件的更正版本将是这样的:

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

}

答案 1 :(得分:0)

每次按一个键都会调用搜索方法,因为你附加了search.component.html中的keyup事件

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

但ngOnInit方法上的代码,更具体地说,是在300毫秒之后调用switchMap方法,前提是,只有当输入值发生变化时才会调用。