首页 > 解决方案 > ngOnInit 中的服务订阅被调用一次,并且不会在路由更改时保持填充

问题描述

只是为了澄清。这个有角度的应用程序正在将数据填充到视图中,但是当我从一个组件导航到另一个组件时,ngOnInit 生命周期挂钩似乎没有被调用,因此这意味着视图上的列表仍然是空的。当我点击 f5(刷新)时,我所在的任何页面上的数据都会被填充,这意味着服务工作正常。可能是生命周期挂钩是问题吗?

因此,鉴于我在文件 product.service.ts 中有以下集合

 export class ProductsService {

  private productsCollection:AngularFirestoreCollection<Product>;
  private products:Observable<Product[]>;

  constructor(private afs:AngularFirestore) { 
    //Code was removed from here as it is beyond the scope of the problem
    //this.products is getting populated here successfully 
  }

 getProducts(){
   return this.products;
 }
}

我从两个单独的组件订阅该方法,如下所示(使用下面相同的确切代码)

constructor(private productService:ProductsService) { }

      ngOnInit() {
        this.productService.getProducts().subscribe(
          products => {
              this.products = products;
          });

因此,假设 componentA 和 componentB 都具有此代码,则在加载两个组件时应在两个组件上填充列表。当我键入组件的 URL 时,列表被填充,但是当我使用 routerlinks 并且数据没有被填充时,就像调用新路由时没有触发 ngOnit 一样。两个视图都显示了列表,但是当我使用 routerlink 而不是写入地址或刷新页面时,它们不会被填充。该服务作为提供者在 app.module.ts 中共享。一些帮助表示赞赏。

标签: angularobservablerouterlinkngoninit

解决方案


使用行为主体而不是可观察的。行为主体是一个热可观察对象,它允许任何订阅者拉取已经推送给它的现有数据。与行为主题的一个区别是您使用 .next 方法推送数据。BehaviorSubjects 在初始化时也需要传递一个初始值,在这种情况下,我传递了 null,因为我假设你的构造函数做了一些事情来获取所需的数据。下面的代码示例:

 export class ProductsService {

     private productsCollection:AngularFirestoreCollection<Product>;
     private products:BehaviorSubject<Product[]> = new BehaviorSubject(null);

     constructor(private afs:AngularFirestore) { 
       //code here to set products
       this.products.next('data to set products here')
     }

     getProducts(){
        return this.products.asObservable();
     }
 }

推荐阅读