Angular 7 - 重用组件以显示过滤后的集合

Angular 7 - reuse component to display filtered collections

我正在尝试使用 MySQL 数据库开发基于 Angular7 的 Web 应用程序项目(提供送餐服务的在线餐厅)。应用程序正在使用路由器在站点上导航和加载组件。

首先,应用程序的重要(受影响)部分-routing.module:

app-routing.module.ts

[...]  
{
path: 'menu',
component: MenuComponent,
children: [
  {
    path: '',
    redirectTo: 'categories',
    pathMatch: 'prefix'
  },
  {
    path: 'categories',
    component: ProductCategoriesComponent,
    resolve: {
      productCategories: CategoriesResolver,
      products: ProductsResolve
    },
  },
  {
    path: 'categories/:id',
    component: ProductsByCategoryComponent,
    resolve: {
      productsByCategory: ProductsResolveByCategory,
      productCategories: CategoriesResolver
    }
  },
  {
    path: '**',
    redirectTo: 'categories',
    pathMatch: 'prefix'
  }
],
  },
[...]

**用例场景如下: I. 用户在导航栏上点击 "Menu" navlink - 正在加载菜单组件: url 动作后的路径:localhost:4200/menu/categories/ **

菜单-component.html

<router-outlet></router-outlet>

这只是加载菜单提供的产品类别的占位符 - Angular 将用户重定向到 menu/categories 并正在加载 ProductCategoriesComponent。这个使用两个解析器 - 实际解析所有产品类别和所有产品(由于没有选择特定类别,它们都被加载)。

类别ID如下: 1 - 开胃菜 2 - 披萨 3 - 意大利面 4 - 饮料 5 - 甜点

** 二。用户选择特定类别后,将过滤整个列表并在后端 returns 具有请求的类别 ID 的新对象列表:**

product.resolve.ts

@Injectable()
export class ProductsResolveByCategory implements Resolve<any> {

  constructor(private productService: ProductService) {
  }

  resolve(route: ActivatedRouteSnapshot) {
    return this.productService.getProductsByCategoryId(route.params['id']);
  }
}

路由将我们引导至例如:localhost:4200/menu/categories/1 当已选择 "appetizers" 类别时。

到目前为止,应用程序运行良好,但出现了在特定条件下显示内容的问题 - 当用户在 /menu/categories/1 并且想要选择另一个类别(例如从 1 更改为 2 ),视图不会自行刷新 - 没有加载具有不同类别 ID 的产品,我们仍然可以看到旧的 - 目前的解决方法是再次单击菜单按钮,然后单击所需的类别。更重要的是,在浏览器中单击 "back"(因此它应该 return 到 menu/categories/)会抛出错误请求(错误 400),因为前端使用 /menu/categories/categories 发送请求(双倍!)而不是 'id'。我找不到任何合乎逻辑的解释,为什么 'id' 被 'categories' 词取代:

products.service.ts

  public getProductsByCategoryId(id: number): Observable<Array<ProductModel>> {
   return this.http.get('/api/products/categories/' + id).pipe(map((response: Array<ProductModel>) => {
   this.productsByCategory = response;
   return this.productsByCategory;
 }));
}

产品-category.component.ts

 Component({
  selector: 'app-products-by-category',
  templateUrl: './products-by-category.component.html',
  styleUrls: ['./../products/products.component.css'],
})
export class ProductsByCategoryComponent implements OnInit {
  private productsByCategory: Array<ProductModel> = [];

  constructor(private productService: ProductService,
              private route: ActivatedRoute) {
  }

   ngOnInit() {
     if (this.route.snapshot.data['productsByCategory']) {
       this.productsByCategory = this.route.snapshot.data['productsByCategory'];
     }
   }
}

所以总结起来,有两个(很可能是逻辑上的愚蠢错误)问题:

  1. 为什么从 menu/categories/1 更改为 menu/categories/2 时,没有加载正确的项目,
  2. 为什么当导航回 /menu/categories/ 时,前端发送 /menu/categories/categories/ 而不是 /menu/categories/ - 作为 'id' 变量,它发送 'categories' 字...(当用户从​​浏览器中的 link 末尾删除 /1 时也会发生此问题)

如有任何帮助,我们将不胜感激。谢谢!

要在您的组件中使用更新,您应该订阅数据,而不是通过快照访问它。使用 this.route.data.subscribe((data) => { this.productsByCategory = data['productsByCategory'];}) 而不是 this.route.snapshot.data['productsByCategory']。 要解决第二个问题,请从路由器配置中删除 path: '' 配置。我认为这就足够了,因为 path: '**' 配置已经处理了这种情况。