【问题标题】:How to use router.navigateByUrl and router.navigate in Angular如何在 Angular 中使用 router.navigateByUrl 和 router.navigate
【发布时间】:2017-12-14 23:20:11
【问题描述】:

https://angular.io/api/router/RouterLink 很好地概述了如何在 Angular4 中创建将用户带到不同路线的链接,但是我找不到如何以编程方式执行相同的操作,而是需要用户单击链接

【问题讨论】:

    标签: angular routes routerlink


    【解决方案1】:

    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'])
    

    两者的区别

    使用router.navigateByUrl类似于更改地址栏 直接——我们提供“完整”的新 URL。然而 router.navigate 通过应用传入的数组创建一个新 URL 命令,一个补丁,指向当前的 URL。

    为了清楚地看到差异,假设当前 URL 是 '/inbox/11/messages/22(popup:compose)'

    使用此 URL,调用 router.navigateByUrl('/inbox/33/messages/44') 将导致 '/inbox/33/messages/44'。但是用 router.navigate(['/inbox/33/messages/44']) 将导致 '/inbox/33/messages/44(popup:compose)'.

    the official docs阅读更多内容。

    【讨论】:

    • 我不太明白,请你把它更简单一些,谢谢提前
    • 什么是“附加”?
    • 这也解决了我的问题,感谢您消除他们的分歧
    【解决方案2】:

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

    /**
     * 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 有更多关于程序化导航的详细信息。

    【讨论】:

    • “总是采用应用于当前的增量”是什么意思?
    • 表示它接受一个相对于当前路由的URL。
    • 如果它导航 relative 到当前路线,我想知道如何在三个中指定向下 down,而不是向上。我想离开路径 /a/b/c 并导航到 a/b 但是 我不想指定从根开始的整个路径。我测试了 navigate(['..']) 但这无济于事。
    【解决方案3】:

    router.navigate 与 router.navigateByUrl

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

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

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

    // 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="../.."
    

    【讨论】:

      【解决方案4】:

      据我了解,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(' ---- String ----');

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

      【讨论】:

        【解决方案5】:

        假设您在 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 你就可以 ie 它首先会尝试匹配 appRoutes 配置,一旦在孩子中找到它就会重定向到 LoadedComponent。代码如下:

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

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

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

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

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

        【讨论】:

          【解决方案6】:

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

          ...
          <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)
                }
              }
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2018-11-03
            • 1970-01-01
            • 2016-11-03
            • 1970-01-01
            • 2018-08-11
            • 2018-09-17
            • 1970-01-01
            • 2018-09-23
            • 2021-07-31
            相关资源
            最近更新 更多