首页 > 解决方案 > 如何将订阅从组件移动到解决

问题描述

在我的组件中的 Angular 应用程序中,我使用从两个 API 获取数据的 switchMap 对两个 Observables 进行了两次订阅,当组件打开时,我必须显示骨架或加载器,我会阻止它,所以我只是阅读有关Resolve的信息,据我所知预加载数据,然后激活路线。

所以我想知道如何将以下订阅从 ngOnInit 移动到解析器

这是我的 ngOnInit 现在的样子

  ngOnInit(): void {
    this.menuService
      .menu(this.idNegozio, this.piva, 'IT')
      .pipe(
        switchMap((menu) =>
          forkJoin([
            of(menu),
            this.pluService.plu(this.idNegozio, this.piva, 'IT'),
          ])
        )
      )
      .subscribe(([menu, plus]) => {
        this.menu = menu;
        this.plus = plus;
        this.filterPlu(menu[0].id);
        if (this.filteredPlu.length) {
          this.ready = true;
        }
      });
  }

相同的组件用于三个路线:

  {
    path: 'asporto',
    component: ProductsComponent,
    canActivate: [ItemsGuardService]
  },
  {
    path: 'takeaway',
    component: ProductsComponent,
  },
  {
    path: 'ecom',
    component: ProductsComponent,
  },

标签: angular

解决方案


创建解析器

@Injectable()
export class MenuResolver implements Resolve<Menu>{
    constructor(private menuService: MenuService, private pluService: PluService) {}

    resolve(route: ActivatedRouteSnapshot): Observable<Menu> {
        const piva = route.parent.params.piva;
        const negozio = route.parent.params.negozio;

        return  this.menuService
        .menu(negozio, piva, 'IT')
        .pipe(
          switchMap((menu) =>
            forkJoin([
              of(menu),
              this.pluService.plu(negozio, piva, 'IT'),
            ])
          ),
          map(([menu, plus]) => ({ menu, plus }))
        );
    }
}

在您的路线定义中使用它并在您的父模块中提供它

const routes: Routes = [
 {
        path: '',
        resolve: { menu: MenuResolver },
        component: Component,
 }
];

@NgModule({
  imports: [
        RouterModule.forChild(routes),
  ],
  providers: [
    MenuResolver,
  ]
})
export class MyModule { }

然后通过 ActivatedRoute 在你的组件中获取它

export class MyComponent {
  menu: Menu;
  plus: MenuDetails;
 
  constructor(private route: ActivatedRoute){}
  
  ngOnInit() {
    const menuData = this.route.snapshot.data.menu;
    this.menu = menuData.menu;
    this.plus = menuData.plus;
  }
}

您必须将解析器添加到所有相关路由,并在组件中以相同的方式使用它


推荐阅读