角度导航到具有不同参数的相同路线

Posted

技术标签:

【中文标题】角度导航到具有不同参数的相同路线【英文标题】: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]" 

也有同样的问题

【问题讨论】:

【参考方案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]));

学分:

    How to reload the current route with the angular 2 router 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 ?

以上是关于角度导航到具有不同参数的相同路线的主要内容,如果未能解决你的问题,请参考以下文章

Nuxtjs/Vuejs 表单数据在导航到不同的路线并使用浏览器后退按钮返回上一个路线时丢失

导航到不同路线后,Flutter 找不到正确的 Provider<Bloc>

同一路线的角力载荷

角度 5 中具有相同 URL 的两个不同组件(通过延迟加载在路由器中传递 slug)

将相同的函数绑定到具有不同参数的窗口调整大小事件

如何使用href链接导航到有角度的路线?