【问题标题】:angular navigate to the same route with different parameter角度导航到具有不同参数的相同路线
【发布时间】:2018-06-08 22:50:16
【问题描述】:

虽然这个问题之前似乎已经出现过,但我找不到适合我的答案,因为路由器似乎在 angular 的整个生命周期中发生了很大变化。

在 Angular 5 中,我有一个希望编辑用户的组件。我使用以下代码导航到该组件:

this.router.navigate(['editsingleuser',user.username])

这会将我发送到 /editsingleuser/bob

然后,在该组件中,我还可以单击一个按钮来编辑我自己的用户详细信息,它使用以下代码:

this.router.navigate(['editsingleuser',this.user.sub])

应该将我发送到 /editsingleuser/joe,但没有

有没有我可以添加到router.navigate 的参数来强制它加载路由,因为它似乎在做某种缓存?

我也尝试过使用

[routerLink]="['editsingleuser',user?.sub]" 

也有同样的问题

【问题讨论】:

    标签: angular angular2-routing


    【解决方案1】:

    我会这样做:

    constructor(private router: Router, private route: ActivatedRoute) { }
    
    /**
     * Navigate to User Details
     *
     * @summary Navigates to User Details Page
     * @param userId: string
     * @returns void
     */
     navigateToUserDetails(userId: string): void {
        this.router.navigate(['.', userId], { relativeTo: this.route.parent });
     }
    

    此解决方案避免了代码中的硬编码 URL 片段。如果 'editsingleuser' URL 片段因某种原因发生更改,可防止出现问题。

    所以,如果您的路由子路径类似于 :userId

    ,我相信这里的技巧是 this.route.parent

    【讨论】:

      【解决方案2】:

      在 Angular 8 中,可以加载一些其他路由,然后返回到当前活动的路由。试试这个:

      this.router.navigateByUrl('/', {skipLocationChange: true})
        .then(()=>this.router.navigate(['editsingleuser',this.user.sub]));
      

      学分:

      1. How to reload the current route with the angular 2 router
      2. https://dev.to/oleksandr/mastering-angular-8-five-things-that-are-good-to-know-to-save-your-time-14hk (Item #5: #5. Reload component on the same URL navigation)

      【讨论】:

      • 它不起作用,它在导航到第二个 url 之前不久导航到第一个 url。
      • 是的,这就是目的:在前往您想去的实际路线之前导航到不同的路线。在这种情况下,正如问题所问的那样,他们想去原来的同一条路线,但参数不同:“角度导航到具有不同参数的同一条路线”
      【解决方案3】:

      从 5.1 开始,Angular 有一个路由重载设置。这是一个名为

      的参数

      onSameUrlNavigation

      https://angular.io/api/router/ExtraOptions

      @NgModule({
        imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' }) ],
        exports: [ RouterModule ]
      })
      export class AppRoutingModule {}
      

      我建议不要使用这种技术。

      当您导航到同一条路线时,Angular 的默认行为不会重新加载路线。这是一个很好的故障保险,而且很有意义。

      但是,如果您要更改参数,您可以订阅参数更改并采取相应的行动,例如:

      @Component({
        selector: 'app-custom-edit',
        templateUrl: './custom-edit.component.html',
        styleUrls: ['./custom-edit.component.scss']
      })
      export class CustomEditComponent implements OnInit {
      
        constructor(private route: ActivatedRoute) { }
      
        ngOnInit() {
          this.route.params.subscribe(res => {
            if (+res.id === 0) this.initNew() // 'id' here is an example url parameter
            else this.initExisting(+res.id)
          })
        }
      
        initNew() {
          //..
        }
      
        initExisting(id: number){
          //..
        }
      }
      

      并且,相应地,您可以根据参数实际处理组件的设置或重置。把它当作你的工作,而不是路由器的工作。此触发器将在第一次初始化和导航到具有不同参数的相同 url 时触发。

      至少,它比重新加载整个路线更有效。

      【讨论】:

        【解决方案4】:

        你想要的并不是 Angular 中的一份奇怪的工作!我在Stackblitz 创建了一个项目,向您展示即使您在同一个组件中,组件将如何再次呈现(重新实例化)。

        注意您应该在 app.routing.module 中为相应的组件定义一个带有参数的路由,如下所示,我为目录定义了username 参数: p>

         RouterModule.forRoot([
              { path: 'login', component: LoginViewComponent },
              { path: 'home', component: HomeViewComponent },
              { path: 'catalog/:username', component: CatalogViewComponent },
              { path: '**', redirectTo: 'login' }
         ])
        

        然后像下面这样导航到它:

        <a routerLink="/catalog/foo">Catalog 1</a> |
        
        <a routerLink="/catalog/bar">Catalog 2</a> 
        

        如果 URL 没有改变你的用作参数的变量有问题。在这种情况下,您使用this.router.navigate[routerLink] 没有区别。

        然后在 catalog.component.ts 处使用它。

        【讨论】:

        • 我不太明白你的回答。 url 改变了,但是没有 RELOAD 组件,没有使用 Michael Meister 提供的解决方案。
        • RELOAD 是什么意思?默认情况下,SPA 平台中没有重新加载。如果你的意思是重新初始化(ngOnInit()),它有
        【解决方案5】:

        我遇到了同样的问题,这在我的情况下解决了它

        constructor(private router: Router) {
            this.router.routeReuseStrategy.shouldReuseRoute = function () {
              return false;
            };
          }
        

        【讨论】:

        • 注意,它会在整个应用程序中禁用 ReuseRoute,从而导致 ngOnDestroy 调用
        • 这触及到问题的核心 imo。为我工作,并解释了直接处理参数更改的替代方法。
        • 这成功了!!!
        【解决方案6】:

        这个问题的答案是我必须在我的 EditSingleUser 组件中订阅路由参数,并在我为页面获取数据时使用这个值

        在 ngOnInit() 中

        this.route.params
          .switchMap((p: Params)=>{
              let usr = p['username']; //read the username route parameter
              return this.apiService.getUser(usr)}      //call getUser with that parameter
                )
          .subscribe(data=> {
            this.user= data
            console.log("data :" + JSON.stringify(data));
            this.setupFormData();          //use the resulting data to set up the form
          })
        

        【讨论】:

          【解决方案7】:

          您无法导航到editsingleuser/joe,因为您已经在editsingleuser 路线中。如果您要从 editsingleuser 导航到相同的路线,则应在您的 editsingleuser 组件中更改以下代码:

          this.router.navigate(['editsingleuser',this.user.sub]);
          

          到这里:

          this.router.navigate(['/editsingleuser',this.user.sub]);
          

          所以你对路由器说,你将去全球路由editsingleuser

          Here我为你创建了一个工作示例。

          【讨论】:

          • 这可能需要更多解释。在 editsingleuser/bob 尝试导航到 editsingleuser/joe 时,是否会被评估为尝试导航到 editsingleuser/bob/editsingleuser/bob ?
          猜你喜欢
          • 1970-01-01
          • 2018-06-12
          • 2021-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多