2017-08-16 14 views
3

私は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はありがとうございましたさ!

+0

あなたは同じもののためplunkerを作成することはできますか?あなたはngOnInitでsubscribeを呼び出しています –

+0

@RahulSingh私は知っています、ngonitは一度トリガーされ、唯一それは購読しています。 :) –

+0

私はあなたのコードをデバッグしようとしましたが、なぜ2回ヒットしたのかの答えを見つけるために、コードは '.switchMap'で中断します。コンポーネント上で 'search()'を呼び出す方法について少し分かりやすくするためには、 'searchTerms'を変更するときにトリガがあるかもしれません。誰かがここから取りたいと思っているなら、私は[plunker here](https://plnkr.co/edit/Acedx2qldUj9fFXKPh3O?p=preview) – BogdanC

答えて

1

サブスクリプションが適切に実装されている場合、「unsubscribe」メソッド、Observableなどとは関係ありません。この動作はAngular自体の仕様です。

https://www.reddit.com/r/Angular2/comments/59532r/function_being_called_multiple_times/d95vjlz/

あなたが開発モードで実行している場合、それは少なくとも二倍の機能 を実行します。開発モードではチェックを行いますので、 は品質検査を行ったと仮定してプロダクションモードが最初の チェックのみを行い、 の値が変更されたポストチェックを解決したことを確認して再確認します。

P.S.これはおそらく、あなたがデベロッパーモードにに直面するだろう次の問題です:)

Angular2 change detection "Expression has changed after it was checked"

0

は、このラインを交換してみてください:

このいずれかで
this.heroes = this.searchTerms 

this.heroes = this.searchTerms.asObservable() 

英雄が観測可能であり、あなたのコードが誤ってそれにnext()を呼び出すことができないことを保証します。

あなたのコードは主人公をSubjectにキャストします。あなたはまだそれでnext()を実行できます。

+0

を作りました。しかし、私を魅了するのは、私が観察可能なものを購読するときにサービスが2度呼ばれるのはなぜですか? –

+0

サブジェクトは、外部サブスクリプションと共有できる内部サブスクリプションを作成します。サブスクリプションがまだ生存しているオブザーバブルにサブジェクトインスタンスを割り当てると、私は推測できます。しかし、これは私の野生の推測です:) –

関連する問題