私はObservableに加入しているときにコンポーネントコードを持っていますが、サービスが2回呼び出されますが、Behaviorsオブジェクトに登録すると1回だけトリガーされます。このアングル2コンポーネントでサービスが2回呼び出されるのはなぜですか?
ログに結果が表示されます私のコンポーネントの下に私のコードを参照してください メソッドsubscribeToMap()メソッドはngOninitで呼び出されます。ここで
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
// Observable class extensions
import 'rxjs/add/observable/of';
// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import { HeroSearchService } from './hero-search-service';
import { Hero } from './../hero';
@Component({
selector: 'hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ],
providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
heroes: Observable<Hero[]>;
private searchTerms = new Subject<string>();
constructor(
private heroSearchService: HeroSearchService,
private router: Router) {}
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
console.log("new " + term);
}
ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => {
return term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([])})
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
this.subscribeToMap();
}
subscribeToMap(): void{
this.heroes.subscribe(() => console.log("called twice"));
this.searchTerms.subscribe(() => console.log("called once"));
}
gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
}
私のサービスのためのコード
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Hero } from './../hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
console.log("service is called");
return this.http
.get(`api/heroes/?name=${term}`)
.map(response => response.json().data as Hero[]);
}
}
verはありがとうございましたさ!
あなたは同じもののためplunkerを作成することはできますか?あなたはngOnInitでsubscribeを呼び出しています –
@RahulSingh私は知っています、ngonitは一度トリガーされ、唯一それは購読しています。 :) –
私はあなたのコードをデバッグしようとしましたが、なぜ2回ヒットしたのかの答えを見つけるために、コードは '.switchMap'で中断します。コンポーネント上で 'search()'を呼び出す方法について少し分かりやすくするためには、 'searchTerms'を変更するときにトリガがあるかもしれません。誰かがここから取りたいと思っているなら、私は[plunker here](https://plnkr.co/edit/Acedx2qldUj9fFXKPh3O?p=preview) – BogdanC