【问题标题】:Reload Angular 4+ route with the same URL parameter使用相同的 URL 参数重新加载 Angular 4+ 路由
【发布时间】:2018-03-20 15:24:01
【问题描述】:

我一直在对重新加载 Angular 4+ 路由进行一些研究,似乎首选方法是改为侦听组件内的 URL 参数更改并在那里重新初始化组件。

我遇到的问题是在 URL 相同(包括参数)的情况下,试图找到一种 DRY(不要重复自己)方法来跨多个组件进行这项工作。在 AngularJS 中,使用 UI-router 很简单。

用例:

我有一个可以“浮动”在任何路线上方的通知面板,当点击通知时,它需要转到与之相关的内容 - 这可以是许多不同类型的内容。

例如:/posts/:id/groups/:id/users/:id

如果用户已经在查看该内容,则不会重新加载和刷新以反映通知消息。即“John Doe 评论了您的帖子”(用户可能正在查看该帖子的过时版本)或“Jane Doe 接受了您加入某个组的请求”(用户可能正在查看该组的访客视图)。

当检测到路由相同时,我确实考虑过使用 window.location.reload(),并且该方法有效,但它非常不受欢迎,因为它会导致开销(角度重新初始化、身份验证检查、套接字重新连接)等)。

任何建议将不胜感激!

【问题讨论】:

  • 您查看过路由器的onSameUrlNavigation 设置吗?默认为ignore,但也有reload 选项。不过,我没有这方面的经验。

标签: angular angular4-router


【解决方案1】:

在这种情况下,您的路线不会改变,只是您的参数会改变。

要解决这个问题,您需要订阅 ActivatedRoute 参数。

export class MyClass implements OnInit {
   constructor(private activatedRoute: ActivatedRoute ) {
        this.activatedRoute.params.subscribe((params)=>{
          console.log('updatedParams', params);
        });
    }
}

【讨论】:

    【解决方案2】:

    您必须订阅路由参数,以便每当它发生变化时我们都可以处理变化。以下是我项目中的示例代码,运行良好。

    constructor(private router: Router) {
        this.route.params.subscribe(params => {
          this.initializePage(params['id']);
        });
    }
    
    initializePage(id:any){
    //..Your code
    // Consider this as your ngOnInIt() method and initialize everything here.
    }
    

    在这里,当参数值在具有相同路由的 URL 中发生变化时,它不会重新加载页面,而只是在我们调用 initializePage(id) 时更改值,这将重新初始化所有内容。

    希望这对您有所帮助。

    【讨论】:

      【解决方案3】:

      当 URL 中没有任何变化时,无法重新加载路由。事实上,您唯一的选择是window.location.reload() 并听取参数更改。

      对于第二个选项,您可以创建一个通用服务来观察查询字符串中id 参数的变化。我们称之为IdWatchService,它看起来像这样:

      @Injectable()
      export class IdWatchService {
        constructor(private route: ActivatedRoute) {
        }
      
        get idChange(): Observable<number | undefined> {
          return this.route.queryParams.map(p => p['id'] as number | undefined).distinctUntilChanged();
        }
      }
      

      然后您可以将此服务添加到需要对更改做出反应的组件(PostsComponentGroupsComponent 等)上的providers 列表中。最后,您可以将其注入到相同的组件中并订阅idChange observable:

      @Component({
        templateUrl: './posts.component.html',
        providers: [
          IdWatchService
        ]
      })
      export class PostsComponent {
        constructor(idWatchService: IdWatchService) {
          idWatchService.idChange.subscribe(id => {
            // Load data for the new ID and refresh the view
          });
        }
      }
      

      【讨论】:

      • 我认为这不是所要求的。来自问题的引用 > 当 URL 相同时(包括参数)
      • @asmmahmud 确实,我明白了。但是,如果没有window.location.reload(),就无法做到这一点。为了清楚起见,我稍微修改了答案。
      【解决方案4】:

      我在 Angular 2 中遇到了相同的场景(非常相似的用例)。就像其他答案所说,我发现在 Angular 中没有内置的方法来做到这一点(也许框架假设应该解决这种情况通过监听参数的变化)。

      和你一样,我不想重写我的代码,所以我使用了一个不同的解决方案,它有点老套,但它不需要太多改变就可以工作。

      我使用的解决方案是在需要重新加载页面的同一层次结构下创建一个虚拟路由。在虚拟路由中,我使用了一个 DummyComponent,它在路由参数中接收数据,该数据描述了我们需要去的下一个路由(我们要重新加载的路由)以及我应该将哪些参数传递给它(例如 id you已经提到),然后我使用注入的 Rounder 类和 Navigation 方法转到该路线。

      我认为这个解决方案将比使用 window.reload 更有效,而且它的编写非常简单。 (我无法复制该代码示例,因为我无权访问该代码)

      【讨论】:

        【解决方案5】:

        我在标题中的通知部分遇到了同样的问题 我已经用 DoCheck 解决了这个问题

        import { Component, DoCheck } from '@angular/core';
        

        在 Class 中实现 DoCheck 接口

        export class HeaderComponent implements DoCheck {
        

        然后使用 ngDoCheck() 方法并验证变量值是否发生变化,它将在您的通知区域中显示相同

        ngDoCheck() {
            // check if values changes
        }
        

        【讨论】:

          【解决方案6】:

          通过this.router.url,您将获得当前页面的网址。比使用路由器导航与 queryParames 一样。以下是将 queryParams 作为分页页面传递的示例。您可以使用类似的方法。

          const url = this.router.url.split('?')[0]; // this will remove previous queryparms
              this.router.navigate([url], { queryParams: { page: $event } });
          

          【讨论】:

            【解决方案7】:

            window.location.reload();

            这对我有用。

            【讨论】:

            • 这将刷新整个页面
            猜你喜欢
            • 1970-01-01
            • 2017-01-24
            • 1970-01-01
            • 2019-02-12
            • 2018-05-01
            • 2017-05-14
            • 1970-01-01
            • 2018-05-01
            • 1970-01-01
            相关资源
            最近更新 更多