32

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

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

我的链接看起来像

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

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

export class LinkoneComponent implements OnInit 
{

    public foo: number;
    constructor() {}

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

}

在路由之间切换时它工作得很好,但是单击当前活动的路由不会导致重新加载组件。

4

12 回答 12

18

目前不支持此功能。如果仅参数值更改但路由保持不变,则不会重新创建组件。

另请参阅https://github.com/angular/angular/issues/9811

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

另请参阅https://stackoverflow.com/a/38560010/217408

于 2016-07-26T12:18:35.320 回答
7

Angular 2-4 当前路线重新加载黑客

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

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]);
    });
  }

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

于 2018-01-22T11:22:47.147 回答
7

从 Angular 5.1 开始,现在可以通过使用onSameUrlNavigation 配置选项作为内置 Angular 路由器的一部分来完成。尽管从文档中看不明显,但设置和开始使用相当简单。

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

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

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

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

paramsChange- 仅在路由参数发生变化时触发,例如在 id/user/: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选项添加到路由文件中的每个路由。

于 2018-01-15T22:21:58.807 回答
3

对我有用,取自:

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

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

于 2018-09-06T07:50:50.077 回答
2

这是我能想出的解决这个烦人问题的最好方法:

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

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

于 2017-06-16T02:52:53.423 回答
1

对于 Angular 2 rc7 - 路由器 3.0

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

于 2016-09-22T05:07:33.203 回答
0

JavaScriptWindow对象公开了一个location成员,该成员具有一个名为 的函数reload

利用,

window.location.reload();

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

于 2021-02-23T00:24:53.047 回答
0

如果您确实需要在每次单击 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);
    }
});

}

希望这可以帮助

于 2019-10-10T18:17:44.103 回答
0
if (currentUrl.indexOf('/settings') > -1) {
    this.router.navigateByUrl('/communication').then(() => this.router.navigateByUrl('/settings'));
} else {
    this.router.navigate(['/settings']);
}
于 2017-08-21T08:13:33.460 回答
0

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

app.module.ts

  • 添加 HashLocationStrategy 和 LocationStrategy

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

  • 添加 NgModule 提供程序

{
   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

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

  • 从导入 PathLocationStrategy@angular/common
import { LocationStrategy, PathLocationStrategy } from '@angular/common';
  • 在提供者中替换HashLocationStrategyPathLocationStrategy
  • 确保您index.html的基本 href 如下所示。

<base href="/">

于 2020-05-01T15:48:27.640 回答
0

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

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

您可以通过为Router.

于 2022-02-07T21:56:29.957 回答
-4

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

于 2017-08-08T07:34:28.423 回答