Saya memiliki kode komponen di sini, ketika saya berlangganan layanan yang dapat diamati, layanan dipanggil dua kali, namun jika saya berlangganan Behaviorsubject, itu hanya dipicu sekali,

Saya dapat melihat di log saya bahwa itulah hasilnya, silakan lihat kode saya di bawah ini untuk komponen saya metode metode subscribeToMap() dipanggil pada 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);
  }
}

Ini kode untuk layanan saya

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

Terima kasih banyak!!!

4
Lego_blocks 16 Agustus 2017, 18:58

2 jawaban

Jawaban Terbaik

Ketika berlangganan diimplementasikan dengan benar, itu tidak ada hubungannya dengan metode "berhenti berlangganan", Dapat diamati, dll. Perilaku ini dirancang oleh Angular itu sendiri.

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

Jika Anda menjalankan dalam mode pengembangan, itu akan menjalankan fungsi setidaknya dua kali. karena dalam mode pengembangan ia melakukan pemeriksaan, perubahan, lalu pemeriksaan ulang untuk memverifikasi, di mana mode produksi hanya melakukan pemeriksaan pertama, dengan asumsi Anda telah melakukan jaminan kualitas dan menyelesaikan nilai apa pun yang dapat diubah setelah pemeriksaan.

P.S. Ini mungkin masalah berikutnya yang akan Anda hadapi dalam Mode Dev :)

Deteksi perubahan Angular2 "Ekspresi telah berubah setelah diperiksa"

3
Anonymous 13 Desember 2017, 19:05

Coba ganti baris ini:

this.heroes = this.searchTerms

Dengan yang ini:

this.heroes = this.searchTerms.asObservable()

Untuk memastikan bahwa pahlawan dapat diamati dan kode Anda tidak dapat memanggil next() secara tidak sengaja.

Kode Anda memberikan pahlawan ke Subjek sehingga Anda masih dapat melakukan next() di atasnya.

0
Yakov Fain 16 Agustus 2017, 17:33