Angular @Input не работает в браузере и компонент не будет отображаться

#angular #typescript #ngxs

#angular #typescript #ngxs

Вопрос:

В родительском компоненте у меня есть список продуктов, который я получаю из магазина:

 // ...
ngOnInit() {
  this.products$.subscribe(products => {
     this.products = products;
  })
}
// ...
  
 <!-- ... -->
  <ng-container *ngIf="products">
    <product-list [products]="products"></product-list>
  </ng-container>
<!-- ... -->
  

И в дочернем product-list :

 // ...
@Input() products: IProduct[];
// ...
  
 <!-- ... -->
  <div *ngFor="let product of products">
    <product-card [product]="product">
  </div>
<!-- ... -->
  

И чем у меня есть каждое product-card шоу product.image .

Проблема, с которой я сталкиваюсь, заключается в том, что когда я попадаю на эту страницу, я могу просматривать все продукты, но когда я нажимаю на что-то на странице, а затем возвращаю браузер на эту страницу, список продуктов не отображается.

У меня нет никаких ошибок в консоли, и я могу подтвердить, что дочерний компонент получает данные при втором рендеринге, добавляя точки отладки в консоль отладки.

Почему мой дочерний компонент отображается только при первом рендеринге? Даже обновление не будет работать. Только когда я перейду на страницу, введя URL-адрес в браузере, я получу тот же компонент для отображения. Заранее спасибо.

Комментарии:

1. Действительно смущен тем, что this.products$ находится в: this.store.select(this.products$) Если это observable, я удивлен, что это работает. Это должен быть селектор.

2. @Richard. Дэвенпорт, я неправильно написал свой пример. Спасибо, что указали на это.

Ответ №1:

ngInit не вызывается при возврате навигации. Используйте ActivatedRoute и подписывайтесь на параметры:

 constructor(route: ActivatedRoute) {
  route.params.subscribe(x => {

  });
}
  

используйте combineLatest, если вы хотите подписаться на оба.
https://www.learnrxjs.io/learn-rxjs/operators/combination/combinelatest

Комментарии:

1. «ngInit не вызывается при возврате навигации». Вы уверены в этом? Я уверен, что это так.

2. @tinnick извините за поздний ответ. Если вы поместите консоль. войдите в своего подписчика. Это срабатывает каждый раз?

3. Да, это так. И я понял, в чем моя проблема 🙂

Ответ №2:

Оказывается, мой верхний компонент не был реализован OnDestroy , и компонент задерживался после перенаправления. Я решил проблему, выполнив следующее:

 @Component({ /* ... */ })
class topComponent implements OnInit, OnDestroy {
  // ...
  private readonly destroy$ = new Subject<void>();

  // ...
  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
}
  

destroy$.[METHOD] Будут удалены все подписанные наблюдаемые объекты, на которые вы подписались с помощью this.[SELECT].pipe(takeUntil(this.destroy$)).subscribe(...) . Довольно аккуратно.

Спасибо за всю вашу помощь!

Комментарии:

1. Вы также можете использовать take (1), если вы знаете, что не будете обновлять хранилище продуктов в компоненте

2. @SalminSkenderovic Да, в зависимости от ситуации, это гораздо лучший подход, поскольку нет необходимости создавать многоадресную рассылку, наблюдаемую, как у меня. Хороший вариант.