【问题标题】:angular 5 routing to same component but different param, not working角度 5 路由到相同的组件但不同的参数,不工作
【发布时间】:2018-09-19 04:54:14
【问题描述】:

我有 Angular 5 基本初级应用程序 只有 5 个组件

我的路由和链接如下所示

//copied from app.module.ts
const appRoutes:Routes = [
  {path:'',component:HomeComponent},
  {path:'items/:cat',component:ItemsComponent},
  {path:'itemdetail/:id',component:ItemdetailComponent},
  {path:'settings',component:SettingsComponent},
];

//copied from navbar.component.html
<ul>
      <li><a [routerLink]="['/']">Home</a></li>
      <li><a [routerLink]="['/items/8']">Rashion</a></li>
      <li><a [routerLink]="['/items/2']">Vegitables</a></li>
      <li><a [routerLink]="['/items/3']">Fruits</a></li>
      <li><a [routerLink]="['/items/7']">Other</a></li>
      <li><a [routerLink]="['/items/5']">Sweets</a></li>
      <li><a [routerLink]="['/settings']">Settings</a></li>          
</ul>

//copied from items.component.ts
ngOnInit(){
    this.cat = this.route.snapshot.params['cat'];
    this.itemsSrv.getItems(this.cat)
            .subscribe((data)=>{
                this.items=data;
            });
}

链接只有在指向不同的组件时才有效,
意味着我可以从主页导航到/items/2
但是当我在项目组件中时,我可以导航到 /items/any-parameter
虽然从项目我可以去主页或设置组件。
简而言之,即使参数不同,它现在也可以导航到相同的组件。

我注意到一件事,网址发生了变化,但页面内容与旧页面相同,没有重新加载新网址:(

【问题讨论】:

  • 详细说明您的问题。我没听懂你在说什么
  • 不要使用特定的参数,但像这样的可选参数:[routerLink]=['/items', {param1:'test'}] 你的路线看起来像这样:/items;param1=test。您只需要在路由上指定不带参数的“项目”
  • @Gilsdav 我试过你的方法,它说:无法匹配任何路线。 URL 段:'items/2'
  • 通过更好地阅读您的问题,我的回答不是您所需要的。页面是否与更改参数之前相同?你怎么拿身份证?我认为组件可能没有重新创建,而只会给你一个参数改变的事件。你订阅参数了吗?
  • items 使用动态参数 (1,2...9) 调用 Web 服务的组件,它根据这些参数返回 fruitssweetsvegitables 等列表跨度>

标签: angular routing navigation


【解决方案1】:

所以,最好的方法是使用 subscribe 来获取 route

userSubscription: Subscription;
...
ngOnInit() {
   this.userSubscription = this.route.params.subscribe(
            (params: Params) => {
                 //------ some code -----
   })
}

之后,您必须退订:

ngOnDestroy(): void {
        this.userSubscription.unsubscribe()
}

【讨论】:

  • 你不需要取消订阅 Angular 创建的 Observables(与你自己创建的 Observables 相对)。 Angular 会处理这个问题。至少在角度 9 中是这样的。我不知道早期版本。
【解决方案2】:

我知道这有点晚了,但我遇到了同样的问题并找到了解决方案。您正在使用 this.route.snapshot.params 获取 id 参数。根据 Angular 文档,仅当您的组件实例永远不会被重用时才使用快照。 Snapshot 仅提供路由参数映射的初始值,不会在组件重用时更新。这意味着如果您通过 id 路由到组件,然后(在显示该组件时)尝试路由到具有不同 id 的同一组件的新实例,则初始组件将被重用,但数据不会更新,因为 ngOnInit()不会被第二次调用。

要解决问题,您必须更改;

this.cat = this.route.snapshot.params['cat'];

使用这种格式;

ngOnInit() {
  this.cat$ = this.route.paramMap.pipe(
    switchMap((params: ParamMap) =>
      this.itemsSrv.getItems(params.get('id')))
  );
}

this.route.paramMap 是从 Observable 返回的,

"暗示路由参数映射可以在生命周期内改变 这个组件”。

您可能必须修改代码的其他部分以使用 Observable (cat$),但由于我只能看到您的部分代码,因此无法就其他更改提供建议。在下面的文档中,里程碑 3 末尾有一个项目文件 (hero-detail.component.ts),展示了它是如何工作的。

你可以在这里阅读官方文档;

Angular2+ Observable paramMap and component reuse

希望这对编码有所帮助!

【讨论】:

    【解决方案3】:

    我认为这是最好的解决方案

    constructor(route:ActivatedRoute) {
     route.params.subscribe(val => {
     // put the code from `ngOnInit` here
      });
    }
    

    路由器只有在导航到不同的路由时才会销毁并重新创建组件。当仅更新路由参数或查询参数但路由相同时,不会销毁和重新创建组件。 很高兴听到是否有帮助。

    【讨论】:

      【解决方案4】:

      当您导航到同一个组件时,Angular 不会重新触发您的 ngOnInit() 方法。要使您的代码正常工作,您将需要使用可观察的 route 参数版本并订阅其更改。请务必阅读Angular Docs about routing。他们那里有很多有用的信息。

      ngOnInit(){
          this.route.paramMap
              .switchMap(params => this.itemsSrv.getItems(params.get('cat')))
              .subscribe(data => {
                  this.items=data;
              });
      }
      

      当您离开此组件时,您需要确保取消订阅此订阅。 Here is a discussion 关于如何做到这一点的最佳实践。

      【讨论】:

        【解决方案5】:

        我在做我的项目时也遇到了这个问题,最好的方法是使用订阅路由而不是使用 Ondestroy 接口取消订阅事件

            ngOnInit{
               this._router.params.subscribe(param =>{
                    // write some code
                   let cat=this._router.snapshot.paramMap.get('cat');
                  });
        }
        

        // 之后你必须取消订阅

            ngOnDestroy(){
            }
        

        【讨论】:

          【解决方案6】:

          发生这种情况是因为 Angular 正在重用该组件。只需使用以下代码停止重用功能,它就会正常工作。

          constructor(private router: Router) {
              // this is for routerLink on same component when only queryParameter changes
              this.router.routeReuseStrategy.shouldReuseRoute = () => false;
            }
          

          【讨论】:

            【解决方案7】:

            如果您尝试使用不同的路由参数路由到同一个组件。这对我有用。

             getConsingmentwithId(id: number){
                this.router.navigate(['component', id], {relativeTo: this.route.parent});
              }
            

            【讨论】:

              【解决方案8】:
               ngOnInit() {
                  this.activeRoute.queryParams.subscribe(queryParams => {
                      //Do something here
                  });
              
                  //Or
              
                  this.activeRoute.params.subscribe(routeParams => {
                      this.loadUserDetail(routeParams.id);
                  });
               }
              

              当我们使用参数创建一个路由以从 API 访问数据时,以下代码有效喜欢这个

                 ngOnInit() {
                      this.loadUserDetail(this.id);
                       // OR
                      this.loadUserDetail();
                   }
              loadUserDetail(id){
                      return this.http.get(this.apiUrl+'/'+ id).subscribe(
                          (res: any) => {
                                this.products = res['data'];
                                this.seoService.updateTitle(this.products[0]['title']);
                                this.seoService.updateOgUrl(this.products[0].keyword);
                              
                            
                 this.seoService.updateDescription(this.products[0].description);
                                console.log(this.products);
                            },
                          (error:HttpErrorResponse) => {
                            console.log('Error in Fetching  Menu');
                            this.products = error.error;
                            console.log(this.products);
                          }
                        );
                   }
              

              抱歉英语不好和解释

              【讨论】:

              • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。
              猜你喜欢
              • 2019-07-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-07
              • 2018-07-11
              • 2021-04-22
              • 2021-01-08
              • 2018-06-08
              相关资源
              最近更新 更多