如何在 Angular 中使用 router.navigateByUrl 和 router.navigate

How to use router.navigateByUrl and router.navigate in Angular

https://angular.io/api/router/RouterLink 很好地概述了如何创建 links 将用户带到 Angular4 中的不同路线,但是我找不到如何以编程方式做同样的事情需要用户点击 link

navigateByUrl

routerLink 指令像这样使用:

<a [routerLink]="/inbox/33/messages/44">Open Message 44</a>

只是对使用 router 及其 navigateByUrl 方法的命令式导航的封装:

router.navigateByUrl('/inbox/33/messages/44')

从消息来源可以看出:

export class RouterLink {
  ...

  @HostListener('click')
  onClick(): boolean {
    ...
    this.router.navigateByUrl(this.urlTree, extras);
    return true;
  }

因此,无论您需要将用户导航到另一条路线,只需注入 router 并使用 navigateByUrl 方法:

class MyComponent {
   constructor(router: Router) {
      this.router.navigateByUrl(...);
   }
}

导航

您可以使用路由器上的另一种方法 - navigate:

router.navigate(['/inbox/33/messages/44'])

两者的区别

Using router.navigateByUrl is similar to changing the location bar directly–we are providing the “whole” new URL. Whereas router.navigate creates a new URL by applying an array of passed-in commands, a patch, to the current URL.

To see the difference clearly, imagine that the current URL is '/inbox/11/messages/22(popup:compose)'.

With this URL, calling router.navigateByUrl('/inbox/33/messages/44') will result in '/inbox/33/messages/44'. But calling it with router.navigate(['/inbox/33/messages/44']) will result in '/inbox/33/messages/44(popup:compose)'.

the official docs 阅读更多内容。

除了提供的答案外,navigate还有更多详细信息。来自函数的评论:

/**
 * Navigate based on the provided array of commands and a starting point.
 * If no starting route is provided, the navigation is absolute.
 *
 * Returns a promise that:
 * - resolves to 'true' when navigation succeeds,
 * - resolves to 'false' when navigation fails,
 * - is rejected when an error happens.
 *
 * ### Usage
 *
 * ```
 * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
 *
 * // Navigate without updating the URL
 * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
 * ```
 *
 * In opposite to `navigateByUrl`, `navigate` always takes a delta that is applied to the current
 * URL.
 */

Router Guide 有更多关于编程导航的详细信息。

router.navigate 与 router.navigateByUrl

router.navigate只是包装router.navigateByUrl的一个方便方法,归结为:

navigate(commands: any[], extras) {
    return router.navigateByUrl(router.createUrlTree(commands, extras), extras);
}

正如其他答案中提到的 router.navigateByUrl 将只接受绝对 URLs:

// This will work
router.navigateByUrl("http://localhost/team/33/user/11")
// This WON'T work even though relativeTo parameter is in the signature
router.navigateByUrl("../22", {relativeTo: route})

所有的相关计算都是由router.createUrlTreerouter.navigate完成的。数组语法用于将每个数组元素视为 URL 修改“命令”。例如。 ".." - 向上,"path" - 向下,{expand: true} - 添加查询参数等。你可以这样使用它:

// create /team/33/user/11
router.navigate(['/team', 33, 'user', 11]);

// assuming the current url is `/team/33/user/11` and the route points to `user/11`

// navigate to /team/33/user/11/details
router.navigate(['details'], {relativeTo: route});

// navigate to /team/33/user/22
router.navigate(['../22'], {relativeTo: route});

// navigate to /team/44/user/22
router.navigate(['../../team/44/user/22'], {relativeTo: route});

{relativeTo: route} 参数很重要,因为这是路由器将用作相关操作的根。

通过组件的构造函数获取它:

  // In my-awesome.component.ts:

  constructor(private route: ActivatedRoute, private router: Router) {}
  
  // Example call
  onNavigateClick() {
    // Navigates to a parent component
    this.router.navigate([..], { relativeTo: this.route })
  }

routerLink 指令

这个指令最好的地方是它会为你检索 ActivatedRoute。在引擎盖下它使用已经熟悉的:

router.navigateByUrl(router.createUrlTree(commands, { relativeTo: route }), { relativeTo: route });

以下变体将产生相同的结果:

[routerLink]="['../..']"

// if the string parameter is passed it will be wrapped into an array
routerLink="../.."

根据我的理解,router.navigate 用于相对于当前路径导航。 例如: 如果我们当前的路径是abc.com/user,我们要导航到url:abc.com/user/10 对于这种情况我们可以使用 router.navigate .


router.navigateByUrl()用于绝对路径导航

如果在这种情况下我们需要导航到完全不同的路线,我们可以使用 router.navigateByUrl

例如,如果我们需要从 abc.com/user 导航到 abc.com/assets,在这种情况下我们可以使用 router.navigateByUrl()


语法:

router.navigateByUrl('----字符串----');

router.navigate([], {relativeTo: 路线})

假设您 运行 您的服务器位于 http://localhost:4200 并且您位于 http://localhost:4200/abc 并且在路由模块下您定义了如下路径:

const appRoutes: Routes = [
{ path: 'abc', component: MainComponent, children: [
    {path: '', component: InitialComponent},
    {path: 'new', component: LoadedComponent}
]}]

现在,我们将从@angular/router 中导入 Router,并将其分配给构造函数(此处为 myRoute)中的任何变量。

import { Router } from '@angular/router';
constructor(private myRoute: Router) { }

现在在您的方法中,您将使用 navigateByUrl 进行重定向,这意味着如果您在 http://localhost:4200/abc 上并尝试使用 navigateByUrl 重定向到 http ://localhost:4200/abc/new 你将能够,即它会首先尝试匹配 appRoutes 配置,一旦在 children 中找到,它将重定向到 LoadedComponent.Code 如下:

this.myRoute.navigateByUrl('abc/new');

此外,如果我们使用 navigate,那么它会基于 activatedRoute 工作,并且它与当前的活动路线有很小的变化:

import { ActivatedRoute, Router } from '@angular/router';
constructor(private myRoute: Router, private activeRoute: ActivatedRoute) { }

在这里,如果我在 http://localhost:4200/abc 并且我有一个方法调用来将它导航到新路线然后它将根据当前活动路线触发并且如果它有新的作为Child 路由然后它将重定向到 http://localhost:4200/abc/new

this.myRoute.navigate(['new'], {relativeTo: this.activeRoute});

我遇到了同样的问题。我的解决方案:

...
<p @click=parseHTML v-html=data.html></p>
...
methods: {
  parseHTML(event) {
    if (event.target.href) {
      event.preventDefault();
      if (event.target.href.includes(location.hostname)) {
        this.$router.push(event.target.href)
      }
    }
  }
}