如何在Angular中刷新组件


84

我正在做一个Angular项目。我正在为组件中的刷新动作而苦苦挣扎。

我想在单击按钮时刷新路由器的组件。当我单击它时,我有刷新按钮,组件/路由器需要刷新。

我尝试过window.location.reload()location.reload()这两个都不适合我的需要。如果有人知道,请帮助。


您可以在这个问题中分享您的代码吗?你尝试过的
Chandru

这是一个复杂的代码,它具有N行代码,难以共享
Sreehari Ballampalli

@Saurabh,通常不需要重新加载组件。您可以具有一个函数(例如,调用“重新启动”),然后在按钮“刷新”中调用该函数。如果您需要订阅更改路径或其他服务,请使用函数ngOnInit-您的组件必须扩展OnInit-,而不是构造函数
Eliseo

这就是我对Angular 9所做的工作stackoverflow.com/a/60909777/1072395
Wlada

Answers:


114

经过研究并按如下所示修改了我的代码,该脚本对我有用。我刚刚添加了条件:

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

1
我在可注射服务中使用它。我换成"your actualComponent"了一个变量。变量设置为this.location.path()调用之前navigateByUrl。这样,无需传递来自调用组件的任何参数或路由的重复/传递。
Tewr

4
您能解释一下什么是“ RefrshComponent”和“ Your actualComponent”吗?
reverie_ss

15
大多数人都可以使用'/'where来使用/RefrshComponent,对于[Your actualComponent"]您来说,只需传递您想重新加载的url(和/或params)即可this.router.navigate(["/items"])。该hack本质上将重定向到顶部URL,然后非常快速地返回到预期的URL,这对于大多数用户而言是不明显的,并且似乎是最简单地实现此目的的hack。
sofly,

2
我同意这绝对可以工作...但是在我的应用程序中失败(角度6)。如果我将其'/'用作虚拟路由,它将(通过redirectTo)转到我的app-routing.module.ts重定向到''(空字符串)的路径上并停止,而不继续进行navigate()调用中的完成路由。如果我使用一个不存在的字符串(例如/foo)作为我的虚拟路由,它将(通过redirectTo)转到我的app-routing.module.ts重定向到**(所有其他内容)的位置,然后再次停止,而不是转到实际路由。奇怪的是,URL栏确实更改为真实路线。对这里有什么不同的想法?
迈克尔·索伦斯

1
如果使用
Tomas Katz

64

使用this.ngOnInit(); 重新加载相同的组件,而不是重新加载整个页面!

DeleteEmployee(id:number)
  {
    this.employeeService.deleteEmployee(id)
    .subscribe( 
      (data) =>{
        console.log(data);

        this.ngOnInit();

      }),
      err => {
        console.log("Error");
      }   
  }

5
尽管这可以回答作者的问题,但缺少一些解释性的单词和/或指向文档的链接。没有一些原始短语的话,原始代码片段不是很有用。您可能还会发现如何写一个好的答案很有帮助。请修改您的答案。
hellow

1
这是比所选答案更好的输入,但缺乏解释。在我的特定情况下,我必须刷新一个子组件。在这种情况下,有几种方法,但是建议使用服务或将事件从父对象广播给子对象。
克劳迪奥

5
同意,这仅在您要从组件内部刷新组件时才有效-如果要处理子组件/外部组件,则this.ngOnInit()将不起作用
astro8891

3
即使它适用于组件,也不会重置表单验证器。
Vicky Gonsalves

1
完美的作品,谢谢。关于AFAIC的解释,代码说明了一切。
Marton Tatai

27

将其添加到所需组件的构造函数的代码中对我有用。

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

this.mySubscription = this.router.events.subscribe((event) => {
  if (event instanceof NavigationEnd) {
    // Trick the Router into believing it's last link wasn't previously loaded
    this.router.navigated = false;
  }
});

确保unsubscribe从这个mySubscriptionngOnDestroy()

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

请参阅此线程以获取更多详细信息 -https://github.com/angular/angular/issues/13831


15

幸运的是,如果您使用的是Angular 5.1+,则由于添加了本机支持,因此不再需要实施hack。您只需要在RouterModule选项中将onSameUrlNavigation设置为“ reload”

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

可在此处找到更多信息:https : //medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2


您也可以使用router.onSameUrlNavigation = 'reload'注入的路由器的属性。
下午3时0zkr

4
使用角度6,对我而言这没有什么区别,也就是说,组件没有重新加载。但是,可接受的答案有效。
Tewr

4
尽管在文档中并不十分清楚,但onSameUrlNavigation旨在重新调用Guards / Resolver,而不是重新加载已路由的组件。有关更多信息,请参见github.com/angular/angular/issues/21115。该解决方案将适用于使用Guards / Resolver的大型,更复杂的应用程序,但对于简单的示例将失败。
sofly,

1
是的,onSameUrlNavigation将再次触发导航事件,但这不会重新加载该组件
Paul Story

6

这有点开箱即用,我不知道这是否对您有帮助,但您尝试过

this.ngOnInit();

它是一个函数,因此无论您在其中拥有什么代码,都将像刷新一样被调用。


3

只需这样做:(对于角度9)

import { Inject } from '@angular/core';    
import { DOCUMENT } from '@angular/common';

constructor(@Inject(DOCUMENT) private document: Document){ }

someMethode(){ this.document.location.reload(); }

2
请阅读OP的评论,刷新整个页面对他来说不是一个选择,它打败了将棱角放在第一位的目的
ihorbond

问题只要求重新加载组件而不是整个页面。
桑托什

2

这可以通过黑客来实现,导航到一些示例组件,然后导航到要重新加载的组件。

this.router.navigateByUrl('/SampleComponent', { skipLocationChange: true });
this.router.navigate(["yourLandingComponent"]);

SampleComponent意味着它应该是空组件还是项目中的另一个组件?
Sreehari Ballampalli

它应该是虚拟的,可以是空的
Sajeetharan

好的,我会尝试
Sreehari Ballampalli

如果我给出的是真,我会收到一条错误消息:[ts]类型'true'与类型'NavigationExtras'没有共同的属性
Sreehari Ballampalli

@SreehariBallampalli检查更新的答案,您需要传递一个对象{skipLocationChange:true}
Sajeetharan

2

在我的应用程序中,我有组件,并且所有数据均来自我在组件的构造函数中调用的API。我通过按钮可以更新页面数据。在按钮上单击,我将数据保存在后端并刷新数据。因此,按照我的要求,重新加载/刷新组件仅是刷新数据。如果这也是您的要求,则使用在组件的构造函数中编写的相同代码。


2

没有显式路由的另一种方法:

async reload(url: string): Promise<boolean> {
  await this.router.navigateByUrl('.', { skipLocationChange: true });
  return this.router.navigateByUrl(url);
}

1

do

// reload page hack methode

push(uri: string) {
    this.location.replaceState(uri) // force replace and no show change
    await this.router.navigate([uri, { "refresh": (new Date).getTime() }]);
    this.location.replaceState(uri) // replace
  }

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

onReload(){
 this.router.navigate(['/servers'],{relativeTo:this.route})
}

0

html文件

<a (click)= "getcoursedetails(obj.Id)" routerLinkActive="active" class="btn btn-danger">Read more...</a>

ts文件

  getcoursedetails(id)
  { 
  this._route.navigateByUrl('/RefreshComponent', { skipLocationChange: true }).then(() => {
    this._route.navigate(["course",id]);
  }); 

-3

这样刷新(硬)角度2中的页面的其他方法 看起来像是f5

import { Location } from '@angular/common';

constructor(private location: Location) {}

pageRefresh() {
   location.reload();
}

1
他说,重新加载整个页面是不合适的,这将重新加载整个页面,而不仅仅是单个/多个组件。
米兰Velebit,

我最终使用了它,除了角度定位服务没有重新加载,所以我使用了窗口。
Paul Story
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.