Saya ingin memahami cara mengamati, subjek, dan perilaku subjek bekerja (telah membaca banyak artikel, menonton banyak video tetapi masih belum jelas bagi saya karena saya gagal menjelaskan perilaku ini) jadi saya membuat contoh sederhana ini dan mendapatkan perilaku yang tidak terduga. Saya memiliki dua komponen, komponen induk dan komponen anak.

Komponen induk menampilkan daftar nama foto dengan tombol untuk menampilkan detail. Ketika tombol ini diklik akan membawa kita ke komponen anak di mana saya ingin menampilkan foto tunggal beserta detailnya. Jadi, inilah idenya.

Saya telah menggunakan layanan di mana saya memiliki subjek. Sekarang setiap kali tombol di komponen induk diklik, saya memancarkan nilai dari subjek. Saya ingin menangkap nilai ini di komponen anak saya, jadi saya berlangganan.

Ada perilaku aneh-- Untuk klik pertama saya tidak melihat data apa pun di komponen anak saya. Klik kedua satu nilai dalam komponen anak. Klik ketiga dua nilai di komponen anak, dan seterusnya....

Berikut adalah komponen saya--

parent.component.ts

export class ParentComponent implements OnInit {
  photoList = [
    {
      albumId: 1,
      id: 1,
      title: "accusamus beatae ad facilis cum similique qui sunt",
      url: "https://via.placeholder.com/600/92c952",
      thumbnailUrl: "https://via.placeholder.com/150/92c952",
    },
    {
      albumId: 1,
      id: 2,
      title: "reprehenderit est deserunt velit ipsam",
      url: "https://via.placeholder.com/600/771796",
      thumbnailUrl: "https://via.placeholder.com/150/771796",
    },
    {
      albumId: 1,
      id: 3,
      title: "officia porro iure quia iusto qui ipsa ut modi",
      url: "https://via.placeholder.com/600/24f355",
      thumbnailUrl: "https://via.placeholder.com/150/24f355",
    },
  ];
  constructor(private _talkService: TalkService, private router: Router) {}

  ngOnInit() {}

  displayName(id, url, thumbnailUrl) {
    console.log({ id, url, thumbnailUrl });

    //this._talkService.talk.emit({ url, thumbnailUrl });
    this._talkService.talk.next({ id, url, thumbnailUrl });
    this.router.navigate(["/photo"]);
  }
}

child.component.ts

export class ChildComponent implements OnInit {
  constructor(private _talkService: TalkService) {}

  ngOnInit() {
    console.log("child component created");
    this._talkService.talk.subscribe((data) => {
      console.log(data);
    });
  }
}

talk.service.ts

@Injectable({
  providedIn: "root",
})
export class TalkService {
  // talk = new EventEmitter();
  talk = new Subject();
  constructor() {}
}

Log konsol keluaran

App with console logs

Saya telah menggunakan tiga ini--

Pemancar Peristiwa-->perilaku yang sama seperti yang dijelaskan Subjek-->perilaku yang sama seperti yang dijelaskan Subjek Perilaku--> Saya mendapatkan nilai pertama juga (Karena membantu kami mendapatkan nilai yang dipancarkan sebelumnya, bagian itu saya mengerti). Penjelasan rinci di sini juga diterima.

Saya mengharapkan satu nilai pada setiap klik, tetapi ini tidak terjadi. Dapatkah seseorang tolong jelaskan saya perilakunya. Itu pasti cara kerja yang bisa diamati dan saya tidak bisa mendapatkannya.

Ini tautan ke repo github saya--

kode sumber github

0
Arpan Banerjee 29 Mei 2020, 13:30

1 menjawab

Jawaban Terbaik

Kedengarannya seperti kebocoran memori klasik. Setiap kali Anda berlangganan talkService.talk, Anda membuat langganan yang hanya akan dibersihkan setelah berhenti berlangganan. Jadi meskipun komponen Anak tampak seperti sedang dihancurkan ketika Anda kembali ke komponen induk, langganan tetap ada dan melakukan log konsol setiap kali subjek talk memancarkan nilai baru. Anda harus berhenti berlangganan ketika komponen Anak dihancurkan. Cara mudah untuk memastikan langganan berhenti berlangganan adalah dengan menggunakan pipa async di template htmlnya.

child.component.ts

export class ChildComponent implements OnInit {
  data$: Observable<any> = this.talkService.talk;

  constructor(private talkService: TalkService) {}
}

child.component.html

<pre>{{ data$ | async }}</pre>

Selain itu, Anda dapat beralih kembali menggunakan BehaviorSubject karena komponen turunan akan berlangganan talk setelah nilai dikeluarkan dari komponen induk.

1
Chris 30 Mei 2020, 19:20