简体   繁体   English

角度6可观察到的自定义对象数组加载一次

[英]Angular 6 Observable of custom object array loads once

I'm developing an application using Angular 6 angularfire2 firestore. 我正在使用Angular 6 angularfire2 firestore开发应用程序。 At first everything looks good, I click (/list) the route to list my objects, the list is ok. 首先,一切看起来都不错,我单击(/列出)列出我的对象的路线,列表就可以了。 But when I click /Home and then again click /list to list again, no list is shown, no errors in console. 但是当我单击/ Home然后再次单击/ list再次列出时,没有显示列表,控制台中没有错误。 but if I refresh the page using F5 the list appears again. 但是如果我使用F5刷新页面,该列表会再次出现。

Any ideas what am I doing wrong? 有什么想法我做错了吗?

My service: 我的服务:



    import { AngularFirestoreCollection, AngularFirestoreDocument, AngularFirestore } from 'angularfire2/firestore';
    import { Personagem } from './../model/personagem';
    import { Observable } from 'rxjs/Observable';
    import { Injectable } from '@angular/core';

    @Injectable({
      providedIn: 'root'
    })
    export class PersonagemService {

      personagens: Observable;
      personagemColl: AngularFirestoreCollection;
      personagemDoc: AngularFirestoreDocument;

      constructor(private afs: AngularFirestore) { 
        this.personagemColl = this.afs.collection('personagem', ref=> ref.orderBy('nome', 'asc'));

        this.personagens = this.personagemColl.snapshotChanges().map(changes=> {
          return changes.map(p => {
            const data = p.payload.doc.data() as Personagem;
            data.id = p.payload.doc.id;
            return data;
          });
        });
      }

      getPersonagens() {
        return this.personagens;
      }

      addPersonagem(personagem: Personagem) {
        this.personagemColl.add(personagem);
      }

      deletePersonagem(personagem: Personagem) {
        this.getPersonagemDoc(personagem)
        this.personagemDoc.delete();
      }

      updatePersonagem(personagem: Personagem) {
        this.getPersonagemDoc(personagem)
        this.personagemDoc.update(personagem);
      }

      getPersonagemDoc(personagem: Personagem) {
        return this.personagemDoc = this.afs.doc(`personagem/${personagem.id}`); 
      }
    }

My Component: 我的组件:



    import { Router } from '@angular/router';
    import { PersonagemService } from './../../services/personagem.service';
    import { Component, OnInit } from '@angular/core';
    import { Observable } from '@firebase/util';
    import { Personagem } from '../../model/personagem';

    @Component({
      selector: 'app-listar-personagem',
      templateUrl: './listar-personagem.component.html',
      styleUrls: ['./listar-personagem.component.css']
    })
    export class ListarPersonagemComponent implements OnInit {

      personagens: Personagem[];

      constructor(private personagemServ: PersonagemService,
        private router: Router) {

      }

      ngOnInit() {
        this.personagemServ.getPersonagens().subscribe(personagens => {
          this.personagens = personagens;
          console.log('lenght', this.personagens.length);
        });
      }

    }

I FIXED IT 我修好了它

I changed the service like this: 我这样更改了服务:



      //personagens: Observable;
      personagemColl: AngularFirestoreCollection;
      personagemDoc: AngularFirestoreDocument;

      constructor(private afs: AngularFirestore) { 
        this.personagemColl = this.afs.collection('personagem', ref=> ref.orderBy('nome', 'asc'));
      }

      getPersonagens$(): Observable {
        return this.personagemColl.snapshotChanges().map(changes=> {
          return changes.map(p => {
            const data = p.payload.doc.data() as Personagem;
            data.id = p.payload.doc.id;
            return data;
          });
        });
      }

And the list component like this: 列表组件是这样的:



      personagens: Personagem[];

      constructor(private personagemServ: PersonagemService,
        private router: Router) {

      }

      ngOnInit() {
        this.personagemServ.getPersonagens$().subscribe(
          personagens => {
            this.personagens = personagens;
          });
      }

Thank you guys 感谢大伙们

Observables do not hold last values. 可观察值不保存最后一个值。 Aka. ka when you subscribe to the personagens: Observable, you have to wait for something to push a new value there. 当您订阅人物角色:可观察时,您必须等待一些将新值推向此处的事物。 So in your case, the first time you refresh, you subscribe to the observable before a value is pushed there. 因此,在您的情况下,第一次刷新时,您先订阅了可观察对象,然后再将值压入该对象。 When the value is pushed, your list is initialized. 推入值后,您的列表将初始化。 When you move to /home and back to /list, you resubscribe to the observable, but since nothing new is pushed to that observable, your list remains uninitialized the second time. 当您移至/ home并返回至/ list时,您将重新订阅该可观察对象,但是由于没有新内容推送到该可观察对象,因此您的列表第二次仍未初始化。

You could look into BehaviourSubject, which is extended from Observable ( http://reactivex.io/RxJava/javadoc/rx/subjects/BehaviorSubject.html ) 您可以查看BehaviourSubject,它是Observable( http://reactivex.io/RxJava/javadoc/rx/subjects/BehaviorSubject.html )的扩展。

在此处输入图片说明

Subject that emits the most recent item it has observed and all subsequent observed items to each subscribed Observer. 发出已观察到的最新项目的主题以及所有随后观察到的项目发送给每个订阅的观察者的主题。

在此处输入图片说明

EDIT 1# 编辑1#

In addition, you do not terminate your subscriptions. 此外,您不会终止订阅。 If you do not terminate them, they are left open in the application, even when the component is destroyed, thus eventually creating a performance bottleneck. 如果不终止它们,即使在组件被破坏的情况下,它们也会在应用程序中保持打开状态,从而最终造成性能瓶颈。

this.personagemServ.getPersonagens().subscribe(personagens => {
          this.personagens = personagens;
          console.log('lenght', this.personagens.length);
        });

Here is a nice article about how to terminate subscriptions gracefully. 这是一篇很好的文章,介绍了如何优雅地终止订阅。

Angular/RxJs When should I unsubscribe from `Subscription` Angular / RxJs我应该何时退订`Subscription`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM