Angular - проблема с перенаправлением [routerLink] в том же модуле

В настоящее время я пытаюсь создать SPA с использованием Angular 9. Я создал модуль под названием products с этим маршрутом localhost: 4200 / products, а для поиска указанного продукта я использую этот маршрут http: // localhost: 4200 / products / (number_id_product)

Я думал реализовать этот компонент каждый раз, когда мне нужно увидеть продукт. Моя проблема заключается в том, что когда я перехожу к другому продукту со страницы текущего продукта, используя ссылку с [routerlink], (http: // localhost: 4200 / products / 1 на http: // localhost: 4200 / products / 2) URL изменяется но страница содержимого не меняется и сохраняет ту же информацию о последнем продукте.

Я не знаю, что происходит с перенаправлением [routerlink]

мой код .ts

import { Component, OnInit } from '@angular/core';
import { Product } from 'src/app/shared/models/product';
import { ActivatedRoute } from '@angular/router';
import { ProductsService } from 'src/app/shared/services/products.service';

@Component({
  selector: 'ec-product-description',
  templateUrl: './product-description.component.html',
  styleUrls: ['./product-description.component.css']
})
export class ProductDescriptionComponent implements OnInit {

  id: string;
  product: Product

  constructor(private route: ActivatedRoute, private service: ProductsService) { }

  ngOnInit(): void {

    this.id= this.route.snapshot.paramMap.get('id')
    //get products/id

    this.service.getProduct(this.id)
      .subscribe(prod=>{
        console.log(`Prod ↓ `)
        console.log(prod)
        this.product=prod
        })

  }

}

мой код html

<div class="container-product">
 <h1>{{product.title}}</h1>
 <img mat-card-image [src]="product.thumbImage">
 <span class="product-descrp">{{product.description}}</span>
 <span [routerLink]="['','products','another_id_product']">See another product!</span>

</div>

person k16style    schedule 06.09.2020    source источник


Ответы (2)


Оба рассматриваемых URL (т.е. /products/1 и /product/2) соответствуют одному и тому же определению пути /products:id. Следовательно, при переходе от /products/1 к /products/2 путь совпадений остается прежним, что означает, что компонент, используемый маршрутизатором, остается прежним. По умолчанию компонент НЕ уничтожается и не визуализируется повторно.

Если вы ожидаете, что ваш компонент будет переключаться между разными идентификаторами продукта, вам следует провести его рефакторинг, чтобы он не считал параметры маршрута только один раз, как вы это делаете в ngOnInit:

this.id= this.route.snapshot.paramMap.get('id')

Вместо этого вам следует наблюдать за изменениями, производимыми маршрутизатором, и соответствующим образом на них реагировать.

    this.route.paramMap.pipe(
      map(paramMap => paramMap.get('id')),
      switchMap(id => this.service.getProduct(id)),
    ).subscribe(prod => {
      console.log(prod)
      this.product = prod
    })

Теперь всякий раз, когда paramMap изменяется, из него будет извлекаться id, и запрос будет выполняться через метод службы getProduct. После получения ответа функция, переданная в метод subscribe, запускается и this.product обновляется.

person Lazar Ljubenović    schedule 06.09.2020

Когда вы программно меняете маршрут с product / 1 на product / 2, компонент не восстанавливается (хорошо, не правда ли). Так что ngOnInit больше не сработает. Это означает, что ваш this.id не изменится, и он не вызовет никаких вызовов getProduct ().

Чтобы исправить это, вам нужно подписаться на параметры, чтобы отслеживать любые изменения в нем.

ngOnInit() {
   this.route.paramMap.subscribe((params: ParamMap) => {
     this.id = params.get('id');
     this.service.getProduct(this.id).subscribe(prod=>{
       ...
     });
   });
}
person Nayak    schedule 06.09.2020
comment
Вложенные подписки являются анти-шаблоном и приводят к утечке памяти. Вместо этого следует использовать switchMap или аналогичный оператор. - person Lazar Ljubenović; 06.09.2020