如何使用angular 2路由器

时间:2016-12-05 20:48:16

标签: angular

我正在使用带有哈希定位策略的角度2。

组件加载了该路由:

"departments/:id/employees"

到目前为止很好。

在成功批量保存多个已编辑的表行后,我想通过以下方式重新加载当前路径URL:

this.router.navigate([`departments/${this.id}/employees`]);

但没有任何反应,为什么?

38 个答案:

答案 0 :(得分:71)

我在Angular的GitHub功能请求中找到了此解决方法:

    open cur for 
        select col_a,
               col_b,
               col_c
        from t_table
        where id_column in (select lt_results(level)
                            from dual
                            connect by level <= ln_count);

我尝试将其添加到我的 app.component.ts this._router.routeReuseStrategy.shouldReuseRoute = function(){ return false; }; this._router.events.subscribe((evt) => { if (evt instanceof NavigationEnd) { this._router.navigated = false; window.scrollTo(0, 0); } }); 功能中,确实有效。现在,对同一链接的所有进一步点击都会重新加载ngOnInit和数据。

Link to original GitHub feature request

归功于GitHub上的 mihaicux2

我在版本component上使用4.0.0-rc.3

对此进行了测试

答案 1 :(得分:61)

现在可以使用Router config的onSameUrlNavigation属性在Angular 5.1中完成此操作。

我添加了一个博客,解释了这里的内容,但其主旨如下

https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2

在路由器配置启用onSameUrlNavigation选项中,将其设置为'reload'。当您尝试导航到已经处于活动状态的路由时,这会导致路由器触发事件​​周期。

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

在路线定义中,将runGuardsAndResolvers设为always。这将告诉路由器始终启动防护和解析器循环,触发相关事件。

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

最后,在您要启用重新加载的每个组件中,您需要处理事件。这可以通过导入路由器,绑定到事件并调用初始化方法来完成,该方法可以重置组件的状态并在需要时重新获取数据。

export class InviteComponent implements OnInit, OnDestroy {
 navigationSubscription;     

 constructor(
   // … your declarations here
   private router: Router,
 ) {
   // subscribe to the router events. Store the subscription so we can
   // unsubscribe later.
   this.navigationSubscription = 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.
 }

 ngOnDestroy() {
   if (this.navigationSubscription) {
     this.navigationSubscription.unsubscribe();
   }
 }
}

完成所有这些步骤后,您应该启用路由重新加载。

答案 2 :(得分:43)

在控制器中创建一个重定向到预期路线的功能,如此

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

然后像这样使用它

this.redirectTo('//place your uri here');

此函数将重定向到虚拟路由并快速返回到目标路由,而无需用户意识到。

答案 3 :(得分:33)

如果您的导航()没有更改已在浏览器地址栏上显示的网址,则路由器无需执行任何操作。刷新数据不是路由器的工作。如果要刷新数据,请创建注入组件的服务并调用服务上的加载功能。如果将检索新数据,它将通过绑定更新视图。

答案 4 :(得分:28)

有点棘手: 使用相同的路径与一些虚拟参数。例如 -

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}

答案 5 :(得分:14)

这就是我对 Angular 9 所做的工作。我不确定这是否适用于旧版本。

您需要在重新加载时调用此名称。

 this.router.navigate([], {
    skipLocationChange: true,
    queryParamsHandling: 'merge' //== if you need to keep queryParams
  })

Router forRoot需要将SameUrlNavigation设置为“重新加载”

 RouterModule.forRoot(appRoutes, {
  // ..
  onSameUrlNavigation: 'reload',
  // ..
})

您的每条路线都需要将runGuardsAndResolvers设置为“ always”(始终)

{
    path: '',
    data: {},
    runGuardsAndResolvers: 'always'
},

答案 6 :(得分:13)

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

答案 7 :(得分:5)

找到一个快速而直接的解决方案,不需要修补角度的内部工作:

基本上:只需创建一个具有相同目标模块的备用路由,然后在它们之间切换:

<ul class="navigation">
    <li routerLink="/gesuch-neu" *ngIf="'gesuch' === getSection()">Gesuch</li>
    <li routerLink="/gesuch" *ngIf="'gesuch' !== getSection()">Gesuch</li>
</ul>

这里的toggeling菜单:

function unique(array, propertyName) {
   return array.filter((e, i) => array.findIndex(a => a[propertyName] === e[propertyName]) === i);
}

希望有所帮助:)

答案 8 :(得分:5)

在参数更改上不会出现重新加载页面。这确实是个好功能。无需重新加载页面,但我们应该更改组件的值。 paramChange方法将调用URL更改。这样我们就可以更新组件数据

/product/: id / details

import { ActivatedRoute, Params, Router } from ‘@angular/router’;

export class ProductDetailsComponent implements OnInit {

constructor(private route: ActivatedRoute, private router: Router) {
    this.route.params.subscribe(params => {
        this.paramsChange(params.id);
    });
}

// Call this method on page change

ngOnInit() {

}

// Call this method on change of the param
paramsChange(id) {

}

答案 9 :(得分:3)

我正在将这个用于Angular 7项目:

reloadCurrentRoute() {
    let currentUrl = this.router.url;
    this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
        this.router.navigate([currentUrl]);
    });
}

答案 10 :(得分:3)

这对我来说就像是魅​​力

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

答案 11 :(得分:3)

对我来说,使用

进行硬编码
this.router.routeReuseStrategy.shouldReuseRoute = function() {
    return false;
    // or
    return true;
};

答案 12 :(得分:2)

有点顽固,但

this.router.onSameUrlNavigation = 'reload';
this.router.navigateByUrl(this.router.url).then(() => {

    this.router.onSameUrlNavigation = 'ignore';

});

答案 13 :(得分:2)

实现OnInit并在route.navigate()方法中调用ngOnInit()

查看示例:

export class Component implements OnInit {

  constructor() {   }

  refresh() {
    this.router.navigate(['same-route-here']);
    this.ngOnInit();   }

  ngOnInit () {

  }

答案 14 :(得分:2)

通过使用reload的虚拟组件和路由解决了类似的情况,它实际上执行了redirect。这肯定不会涵盖所有用户场景,但只适用于我的场景。

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http';

@Component({
  selector: 'reload',
  template: `
    <h1>Reloading...</h1>
  `,
})
export class ReloadComponent implements OnInit{
  constructor(private router: Router, private route: ActivatedRoute) {
  }

  ngOnInit() {
    const url = this.route.snapshot.pathFromRoot.pop().url.map(u => u.path).join('/');
    this.router.navigateByUrl(url);
  }
}

使用通配符连接路由以捕获所有URL:

import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { LoginViewComponent } from './views/login/login.component';
import { HomeViewComponent } from './views/home/home.component';
import { ReloadComponent } from './views/reload/reload.component';

@NgModule({
  declarations: [ 
    LoginViewComponent, HomeViewComponent, ReloadComponent
  ],
  imports: [
    RouterModule.forRoot([
      { path: 'login', component: LoginViewComponent },
      { path: 'home', component: HomeViewComponent },
      { 
        path: 'reload',
        children: [{
          path: '**',
          component: ReloadComponent 
        }]
      },
      { path: '**', redirectTo: 'login'}
    ])
  ],
  exports: [
    RouterModule,
  ],
  providers: [],

})
export class AppRoutingModule {}

要使用此功能,我们只需要将重新加载添加到我们要去的网址:

  this.router.navigateByUrl('reload/some/route/again/fresh', {skipLocationChange: true})

答案 15 :(得分:2)

就我而言:

const navigationExtras: NavigationExtras = {
    queryParams: { 'param': val }
};

this.router.navigate([], navigationExtras);

工作正确

答案 16 :(得分:1)

有多种方法可以刷新当前路线

更改路由器行为(自Angular 5.1起) 将路由器的onSameUrlNavigation设置为“重新加载”。这将在同一URL导航上发出路由器事件。

  • 然后您可以通过订阅路线来处理它们
  • 您可以将其与runGuardsAndResolvers结合使用以重新运行解析器

保持路由器不变

  • 在URL中传递带有当前时间戳的刷新queryParam,并 订阅路由组件中的queryParams。
  • 使用路由器插座的Activate Event获取一个 保留路由组件。

我在https://medium.com/@kevinkreuzer/refresh-current-route-in-angular-512a19d58f6e下写了更详细的解释

希望这会有所帮助。

答案 17 :(得分:1)

Router导入ActivatedRoute@angular/router

import { ActivatedRoute, Router } from '@angular/router';

注入RouterActivatedRoute(以防您需要URL中的任何内容)

constructor(
    private router: Router,
    private route: ActivatedRoute,
) {}

根据需要从URL获取任何参数。

const appointmentId = this.route.snapshot.paramMap.get('appointmentIdentifier');

使用技巧,方法是导航到虚拟或主URL,然后导航到实际URL,将刷新组件。

this.router.navigateByUrl('/appointments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`appointment/${appointmentId}`])
});

以您为例

const id= this.route.snapshot.paramMap.get('id');
this.router.navigateByUrl('/departments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`departments/${id}/employees`]);
});

如果您使用虚拟路由,那么如果您实现了未找到的网址(如果与任何网址都不匹配),则会看到标题闪烁“未找到”。

答案 18 :(得分:1)

我相信这在Angular 6+中已经(本来)解决了;检查

但这适用于整个路线(也包括所有子路线)

如果要定位单个组件,请按以下步骤操作: 使用变化的查询参数,以便您可以随意导航多次。

在导航点(类)

   this.router.navigate(['/route'], {
        queryParams: { 'refresh': Date.now() }
    });

在您要“刷新/重新加载”的组件中

// . . . Component Class Body

  $_route$: Subscription;
  constructor (private _route: ActivatedRoute) {}

  ngOnInit() {
    this.$_route$ = this._route.queryParams.subscribe(params => {
      if (params['refresh']) {
         // Do Something
         // Could be calling this.ngOnInit() PS: I Strongly advise against this
      }

    });
  }

  ngOnDestroy() {
    // Always unsubscribe to prevent memory leak and unexpected behavior
    this.$_route$.unsubscribe();
  }

// . . . End of Component Class Body

答案 19 :(得分:0)

enter image description here

同一条路线重新加载Angular 6

答案 20 :(得分:0)

非常令人沮丧的是,Angular still 似乎没有为此提供好的解决方案。我在这里提出了一个github问题:https://github.com/angular/angular/issues/31843

同时,这是我的解决方法。它建立在上面建议的其他一些解决方案的基础上,但我认为它更强大。它涉及将路由器服务包装在“ ReloadRouter”中,该服务负责重新加载功能,还向核心路由器配置添加了RELOAD_PLACEHOLDER。这用于临时导航,避免触发任何其他路线(或警卫)。

注意:只有在您想要重新加载功能时,才使用ReloadRouter。否则,请使用普通的Router

import { Injectable } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class ReloadRouter {
  constructor(public readonly router: Router) {
    // Note that this is the root-level Router instance, because ReloadRouter is provided in 'root'
    router.config.unshift({ path: 'RELOAD_PLACEHOLDER' });
  }

  public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
    return this.router
      .navigateByUrl('/RELOAD_PLACEHOLDER', {skipLocationChange: true})
      .then(() => this.router.navigate(commands, extras));
  }
}

答案 21 :(得分:0)

您应该在RouterModule中使用“ onSameUrlNavigation”属性,然后订阅Route事件 https://blog.angularindepth.com/refresh-current-route-in-angular-512a19d58f6e

答案 22 :(得分:0)

一种解决方案是传递一个虚拟参数(即以秒为单位的时间),这样始终可以重新加载链接:

{{1}}

答案 23 :(得分:0)

确定何时应存储路线将false返回给

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

并将路由器的导航值设置为false,表明此路由从未路由

this.mySubscription = this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
        this.router.navigated = false;
    }
});

答案 24 :(得分:0)

我尝试了一些修复程序,但均无效果。我的版本很简单:在查询参数中添加一个新的未使用参数

## eureka.client.eureka-server-port=8761 // on which port server is running

答案 25 :(得分:0)

解决方案:

订阅 URL 参数并在那里初始化组件。 没有技巧,只是“新网址 --> 新数据”,包括首次加载。

对于网址参数(如 /persons/:id):

constructor(protected activeRoute: ActivatedRoute, ...) {
    this.activeRoute.paramMap.subscribe(paramMap => {
        const id = paramMap.get('id');    // get param from dictonary
        this.load(id);                    // load your data
    });
}

对于 URL 查询参数(如 ?q=...&returnUrl=...)(通常不需要):

    this.activeRoute.queryParamMap.subscribe(queryParamMap => {
        const returnUrl = queryParamMap.get('returnUrl');
        ...
    });

问题的原因是:

当 URL 发生变化时,Angular 会尽可能重用旧组件以节省计算机资源。加载数据是您的自定义代码,因此 Angular 无法为您做。

答案 26 :(得分:0)

另一种选择是使用纯 js,但页面实际上会刷新。

window.location.reload(true)

答案 27 :(得分:0)

据我所知,Angular 2中的路由器无法做到这一点。但是您可以这样做:

window.location.href = window.location.href

要重新加载视图。

答案 28 :(得分:0)

下面的代码将起作用:

logoFn(url: any) {

    this.router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
    };
    this.router.navigate(['']); or
    this.router.navigate([url]);

}

答案 29 :(得分:0)

如果您要通过 Router Link 更改路线,请执行以下操作:

  constructor(public routerNavigate: Router){

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

          this.router.events.subscribe((evt) => {

            if (evt instanceof NavigationEnd) {

                this.router.navigated = false;
             }
          })
      }

答案 30 :(得分:0)

我正在使用setTimeoutnavigationByUrl来解决此问题...并且它对我来说很好。

它被重定向到其他URL,而是再次出现在当前URL中...

 setTimeout(() => {
     this.router.navigateByUrl('/dashboard', {skipLocationChange: false}).then(() =>
           this.router.navigate([route]));
     }, 500)

答案 31 :(得分:0)

订阅路线参数更改

    // parent param listener ie: "/:id"
    this.route.params.subscribe(params => {
        // do something on parent param change
        let parent_id = params['id']; // set slug
    });

    // child param listener ie: "/:id/:id"
    this.route.firstChild.params.subscribe(params => {
        // do something on child param change
        let child_id = params['id'];
    });

答案 32 :(得分:0)

假设要刷新的组件路由为view,请使用此命令:

this.router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
  if (future.url.toString() === 'view' && curr.url.toString() === future.url.toString()) {
    return false;
  }
  return (future.routeConfig === curr.routeConfig);
}; 

您可以在方法中添加debugger,以了解导航到"departments/:id/employees"后确切的路线是什么。

答案 33 :(得分:-2)

reload current route in angular 2 非常有用的链接,可以在angualr 2或4中重新加载当前路由

在此定义两种技术来做到这一点

  1. with dummy query params
  2. with dummy route
  3. 了解更多信息,请参阅上面的链接

答案 34 :(得分:-2)

window.location.replace

// use backtick to enclose the route
window.location.replace(`departments/${this.id}/employees`)

答案 35 :(得分:-2)

这对我有用:

let url = `departments/${this.id}/employees`;

this.router.navigated = false;
this.router.navigateByUrl(url);

答案 36 :(得分:-4)

试试这个

  

window.open('dashboard','_ self');

它的旧方法,但适用于所有角度版本,它在路线上重定向并刷新页面。

答案 37 :(得分:-22)

只需使用原生的javascript重载方法:

reloadPage() {
    window.location.reload();
}