不能reload/refresh活动路线

Can't reload/refresh active route

我最近更新到了新的 RC3 和 Router3alpha,似乎有些事情发生了变化。

我注意到单击活动路线的 link 不会再导致组件重新加载。我如何使用新的 router3 实现此行为?

我的link长得像

<a [routerLink]="['/link1']">Link1</a>

为了测试,我只是在 ngOnInit 中使用了一个随机数:

export class LinkoneComponent implements OnInit 
{

    public foo: number;
    constructor() {}

    ngOnInit() 
    {
        this.foo = Math.floor(Math.random() * 100) + 1;
    }

}

在路由之间切换时工作正常,但单击当前活动路由不会导致组件重新加载。

目前不支持。如果只有参数值发生变化但路由保持不变,则不会重新创建组件。

另见 https://github.com/angular/angular/issues/9811

您可以订阅参数以在参数更改以重新初始化组件实例时收到通知。

另见

对于 Angular 2 rc7 - 路由器 3.0

将 index.html 中的基数 url 更改为 <script>document.write('<base href="/" />');</script>

这是我能够想出的解决这个恼人问题的最佳技巧:

    var currentUrl = this.router.url;
    var refreshUrl = currentUrl.indexOf('someRoute') > -1 ? '/someOtherRoute' : '/someRoute';
    this.router.navigateByUrl(refreshUrl).then(() => this.router.navigateByUrl(currentUrl));

这行得通,但它仍然是一个 hack,我讨厌 Angular 团队没有提供 reload() 方法

在我看来,您可以在打字稿中使用 window.location.reload()。 这种方式既简单又安全,因为它是浏览器功能的一部分。

if (currentUrl.indexOf('/settings') > -1) {
    this.router.navigateByUrl('/communication').then(() => this.router.navigateByUrl('/settings'));
} else {
    this.router.navigate(['/settings']);
}

从 Angular 5.1 开始,现在可以使用 onSameUrlNavigation 配置选项作为内置 Angular 路由器的一部分。虽然从文档中看不出来,但设置和开始使用起来相当简单。

您需要做的第一件事是在您的 app.routing.ts 中设置选项(如果您有一个或配置了应用程序路由的文件)。

onSameUrlNavigation 有两个可能的值 'reload'false。默认值是 false ,当路由器被要求导航到活动路由时,它不会发生任何事情。我们想将此值设置为 reload。值得注意的是 reload 实际上并没有做重新加载路由的工作,它只是重新触发我们需要挂钩的路由器上的事件。

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

要确定这些事件实际触发的时间,您需要在路由中指定 runGuardsAndResolvers 配置选项。这可以取三个值...

paramsChange - 仅在路由参数发生变化时触发,例如/user/:id 中的 id 更改

paramsOrQueryParamsChange - 当路由参数改变或查询参数改变时触发。例如idlimit 属性 在 /user/:id/invites?limit=10

中的变化

always - 导航路线时始终触发

我们想在这种情况下始终指定。示例路线如下所示。

export const routes: Routes = [
  {
    path: 'invites',
    component: InviteComponent,
    children: [
      {
        path: '',
        loadChildren: './pages/invites/invites.module#InvitesModule',
      },
    ],
    canActivate: [AuthenticationGuard],
    runGuardsAndResolvers: 'always',
  }
]

那是你配置的路由器。下一步是实际处理您的一个组件中的事件。您需要将路由器导入到您的组件中,然后挂接到事件中。在这个例子中,我已经连接到 NavigationEnd 事件,一旦路由器完成从一个路由到下一个路由的导航,该事件就会被触发。由于我们配置应用程序的方式,即使您尝试导航到当前路线,它现在也会触发。

export class InviteComponent implements OnInit {
  constructor(
    // ... your declarations here
    private router: Router,
  ) {
    // subscribe to the router events
    this.router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        this.initialiseInvites();
      }
    });
  }

  initialiseInvites() {
    // Set default values and re-fetch any data you need.
  }
}

繁重的工作进入了 initialiseInvites() 方法,在这里您可以将属性重置为其默认值并从服务中获取数据以使组件恢复到其初始状态。

您需要在每个希望能够在单击时重新加载或通过某种形式的刷新按钮刷新的组件重复此模式,确保将 runGuardsAndResolvers 选项添加到路由中的每个路由文件。

Angular 2-4 当前路由重载 hack

对我来说,使用此方法有效:

onRefresh() {
  this.router.routeReuseStrategy.shouldReuseRoute = function(){return false;};

  let currentUrl = this.router.url + '?';

  this.router.navigateByUrl(currentUrl)
    .then(() => {
      this.router.navigated = false;
      this.router.navigate([this.router.url]);
    });
  }

您可以将此方法附加到当前组件上的单击事件以重新加载它。

这对我有用,摘自 :

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

现在您可以像这样使用:this.redirectTo(this.router.url)

如果你真的需要欺骗 Router 在每次点击 routerLink 时重新加载组件,你可以在你的组件中使用下面的代码

constructor(private router: Router){
 // override the route reuse strategy
 this.router.routeReuseStrategy.shouldReuseRoute = function(){
    return false;
 }

 this.router.events.subscribe((evt) => {
    if (evt instanceof NavigationEnd) {
       // trick the Router into believing it's last link wasn't previously loaded
       this.router.navigated = false;
       // if you need to scroll back to top, here is the right place
       window.scrollTo(0, 0);
    }
});

}

希望对您有所帮助

我遇到了同样的问题,我在我的应用程序模块中使用 LocationStrategy 解决了它。这就是我如何实施并将解决所有路由问题的方法。

app.module.ts

  • 添加 HashLocationStrategy 和 LocationStrategy

    import { HashLocationStrategy, LocationStrategy } from '@angular/common';

  • 添加 NgModule Provider

{
   provide: LocationStrategy,
   useClass: HashLocationStrategy
 }

最终版 app.module.ts 看起来像这样

import { NgModule }       from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import { HashLocationStrategy, LocationStrategy } from '@angular/common';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule],
    providers: [
                  {
                     provide: LocationStrategy, 
                     useClass: HashLocationStrategy
                  }
                ],
})

export class AppModule {}

有关更多信息,您可以访问这些链接 HashLocationSt

注意: 上述策略会在您的 URL 中添加 #,我不喜欢。所以我使用了替代方法:

替代方法

除了使用 HashLocationStrategy,您还可以使用 PathLocationStrategy

按照以下步骤删除 # 并且在上述方法中也能按预期工作

  • @angular/common 导入 PathLocationStrategy
import { LocationStrategy, PathLocationStrategy } from '@angular/common';
  • 将供应商中的HashLocationStrategy替换为PathLocationStrategy
  • 确保您的 index.html 具有如下所示的基本 href。

<base href="/">

JavaScript Window 对象公开了一个 location 成员,该成员具有一个名为 reload.

的函数

使用,

window.location.reload();

参考: https://www.w3schools.com/jsref/met_loc_reload.asp

在 Angular 12+ 上,您可以执行以下操作:

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.navigate(url);

您可以通过为 Router 创建一个包装器来实现 site-wide。