我正在同一页上使用一些查询字符串参数调用router.navigate
。在这种情况下,ngOnInit()
不会被调用。这是默认行为还是我需要添加其他内容?
我正在同一页上使用一些查询字符串参数调用router.navigate
。在这种情况下,ngOnInit()
不会被调用。这是默认行为还是我需要添加其他内容?
您可以注入 ActivatedRoute
并订阅 params
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
仅当路由导航到不同的路由时,路由器才会销毁并重新创建组件。当仅更新路由参数或查询参数但路由相同时,组件不会被销毁和重新创建。
强制重新创建组件的另一种方法是使用自定义重用策略。另请参见Angular2 router 2.0.0 not reloading components when same url loaded with different parameters?(目前似乎没有太多可用的实现信息)
您可以在路由器上调整reuseStrategy。
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
:RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
。不过我不能保证其他版本的Angular也是如此。 - Hildyfunction()
)吗?如果您创建了一个名为 routing.module.ts 的新文件,它应该如何与其他文件交互?还有一个名为 app-routing.module.ts 的文件是自动创建的。 - edn我使用过以下内容,它有效。
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
触发一次? - Halfistrouter.navigate()
导航到相同的URL,它将再次触发ngOnInit
。 - Caveman你是否需要重新加载页面?这是我的解决方案:我改变了@NgModule(在我的情况下是app-routing.module.ts文件):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
在您的导航方法中,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
router.navigate()
到相同的URL,它将再次触发ngOnInit
。 - Caveman这是一个包含更多信息的最佳想法集合
解决方案1 - 使用params订阅:
教程:https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
文档:https://angular.io/api/router/ActivatedRoute#params
在使用参数变量的每个路由组件中,都应该包含以下内容:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit, OnDestroy {
paramsSub: Subscription;
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// ...
this.paramsSub = this.activeRoute.params.subscribe(val => {
// Handle param values here
});
// ...
}
// ...
public ngOnDestroy(): void {
// Prevent memory leaks
this.paramsSub.unsubscribe();
}
}
这段代码常见的问题是订阅是异步的,可能会更加棘手。此外,在 ngOnDestroy 中不能忘记取消订阅,否则会发生糟糕的事情。
好消息是,这是处理此问题的最常见和最有文档记录的方法。使用此方法还有一个性能提升,因为您可以重用模板,而不是每次访问页面时销毁并重新创建。
解决方案2 - shouldReuseRoute / onSameUrlNavigation:
文档: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
文档: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
文档: https://angular.io/api/router/ActivatedRouteSnapshot#params
找到项目中 RouterModule.forRoot
的位置(通常在 app-routing.module.ts 或 app.module.ts 中):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
然后在AppComponent中添加以下内容:
import { Component, OnInit} from '@angular/core';
import { Router } from '@angular/router';
// ...
@Component({
// ...
})
export class AppComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
// Allows for ngOnInit to be called on routing to the same routing Component since we will never reuse a route
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
// ...
}
// ...
}
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit {
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// Handle params
const params = +this.activeRoute.snapshot.params;
// ...
}
// ...
}
这种解决方案的常见问题是它并不常见。另外,您正在改变 Angular 框架的默认行为,因此可能会遇到其他人通常不会遇到的问题。
好处在于所有代码都是同步的,更容易理解。
NgOnInit
会在实例创建时被调用一次。对于同一个实例,NgOnInit
不会再次被调用。如果想要调用它,需要销毁已创建的实例。
我曾经遇到过同样的问题,此外,我还收到了警告:
did you forget to call `ngZone.run()`
这个 网站提供了最好的解决方案:
import { Router } from '@angular/router';
import { NgZone } from '@angular/core';
...
constructor(
private ngZone:NgZone,
private _router: Router
){ }
redirect(to) {
// call with ngZone, so that ngOnOnit of component is called
this.ngZone.run(()=>this._router.navigate([to]));
}
解决方案可能是订阅您的路由器事件。
导入Router
和NavigationEnd
import { Router, NavigationEnd } from '@angular/router';
在构造函数中初始化路由器。
constructor(router: Router) {
this.router.events.subscribe((ev) => {
if (ev instanceof NavigationEnd) {
//do something
}
});