路由器导航在同一页面时不调用 ngOnInit
Router Navigate does not call ngOnInit when same page
我在同一页面上使用一些查询字符串参数调用 router.navigate
。在这种情况下,ngOnInit()
不会调用。是默认设置还是我需要添加其他任何东西?
您可以注入 ActivatedRoute
并订阅 params
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
路由器仅在导航到不同路线时销毁并重新创建组件。当仅更新路由参数或查询参数但路由相同时,组件不会被销毁并重新创建。
另一种强制重新创建组件的方法是使用自定义重用策略。另请参阅 (似乎没有太多可用信息,但如何实现它)
NgOnInit
会在创建实例时调用一次。对于同一个实例 NgOnInit
将不会被再次调用。为了调用它,必须销毁创建的实例。
考虑将您在 ngOnInit 中的代码移动到 ngAfterViewInit 中。
后者似乎是在路由器导航上调用的,在这种情况下应该对您有所帮助。
您可以在路由器上调整reuseStrategy。
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
这个问题可能是因为您没有使用 ngOnDestroy 终止订阅。这是完成的方法。
引入以下rxjs订阅导入。
import { Subscription } from 'rxjs/Subscription';
将 OnDestory 添加到您的 Angular 核心导入。
import { Component, OnDestroy, OnInit } from '@angular/core';
将 OnDestory 添加到您的导出 class。
export class DisplayComponent implements OnInit, OnDestroy {
在您的导出 class 下为组件上的每个订阅创建一个值为 Subscription from rxjs 的对象 属性。
myVariable: Subscription;
将您的订阅值设置为 MyVariable:订阅。
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
然后在 ngOninit 正下方放置 ngOnDestory() 生命周期挂钩,并放入您的取消订阅声明以进行订阅。如果您有多个,请添加更多
ngOnDestroy() {
this.myVariable.unsubscribe();
}
您可能需要重新加载页面吗?这是我的解决方案:我已经更改了 @NgModule(在 app-routing.module.ts 文件在我的例子中):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
当您想在同一页面上进行路由导航并调用 ngOnInit() 时,您可以这样做,例如,
this.router.navigate(['category/list', 类别])
.then(() => window.location.reload());
为路由数组中的同一组件创建不同的路径。
常量路线:路线= [{
路径:"app",
组件:我的组件
},
{
路径:"app-reload",
组件:我的组件
}];
如果当前URL是"app"
然后使用 "app-reload" 导航,反之亦然。
这是此页面上最好的想法的集合以及更多信息
解决方案 1 - 使用参数订阅:
教程: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 框架的默认行为,因此您可以 运行 处理人们通常不会 运行 处理的问题。
好消息是您的所有代码都是同步的并且更易于理解。
Angular 9
我已经使用了以下并且有效。
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
关于您的导航方法,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
我遇到了同样的问题,另外我收到了警告:
did you forget to call `ngZone.run()`
This 站点提供了最佳解决方案:
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 Navigate 在同一页面
时不调用 ngOnInit
函数的最佳解决方案
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
// this code is for redirecting to the dashboard page with calling ngOnInIt
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['./dashboard']);
这应该有效,并且只应用于特殊情况。当您在重定向后不必导航很多时,您可以使用 this.otherwise 这有时会搞砸。请注意,您始终可以在需要时将 'routeReuseStrategy' 设置为 true。
我在同一页面上使用一些查询字符串参数调用 router.navigate
。在这种情况下,ngOnInit()
不会调用。是默认设置还是我需要添加其他任何东西?
您可以注入 ActivatedRoute
并订阅 params
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
路由器仅在导航到不同路线时销毁并重新创建组件。当仅更新路由参数或查询参数但路由相同时,组件不会被销毁并重新创建。
另一种强制重新创建组件的方法是使用自定义重用策略。另请参阅
NgOnInit
会在创建实例时调用一次。对于同一个实例 NgOnInit
将不会被再次调用。为了调用它,必须销毁创建的实例。
考虑将您在 ngOnInit 中的代码移动到 ngAfterViewInit 中。 后者似乎是在路由器导航上调用的,在这种情况下应该对您有所帮助。
您可以在路由器上调整reuseStrategy。
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
这个问题可能是因为您没有使用 ngOnDestroy 终止订阅。这是完成的方法。
引入以下rxjs订阅导入。
import { Subscription } from 'rxjs/Subscription';
将 OnDestory 添加到您的 Angular 核心导入。
import { Component, OnDestroy, OnInit } from '@angular/core';
将 OnDestory 添加到您的导出 class。
export class DisplayComponent implements OnInit, OnDestroy {
在您的导出 class 下为组件上的每个订阅创建一个值为 Subscription from rxjs 的对象 属性。
myVariable: Subscription;
将您的订阅值设置为 MyVariable:订阅。
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
然后在 ngOninit 正下方放置 ngOnDestory() 生命周期挂钩,并放入您的取消订阅声明以进行订阅。如果您有多个,请添加更多
ngOnDestroy() { this.myVariable.unsubscribe(); }
您可能需要重新加载页面吗?这是我的解决方案:我已经更改了 @NgModule(在 app-routing.module.ts 文件在我的例子中):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
当您想在同一页面上进行路由导航并调用 ngOnInit() 时,您可以这样做,例如,
this.router.navigate(['category/list', 类别]) .then(() => window.location.reload());
为路由数组中的同一组件创建不同的路径。
常量路线:路线= [{ 路径:"app", 组件:我的组件 }, { 路径:"app-reload", 组件:我的组件 }];
如果当前URL是"app" 然后使用 "app-reload" 导航,反之亦然。
这是此页面上最好的想法的集合以及更多信息
解决方案 1 - 使用参数订阅:
教程: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 框架的默认行为,因此您可以 运行 处理人们通常不会 运行 处理的问题。
好消息是您的所有代码都是同步的并且更易于理解。
Angular 9
我已经使用了以下并且有效。
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
关于您的导航方法,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
我遇到了同样的问题,另外我收到了警告:
did you forget to call `ngZone.run()`
This 站点提供了最佳解决方案:
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 Navigate 在同一页面
时不调用ngOnInit
函数的最佳解决方案
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
// this code is for redirecting to the dashboard page with calling ngOnInIt
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['./dashboard']);
这应该有效,并且只应用于特殊情况。当您在重定向后不必导航很多时,您可以使用 this.otherwise 这有时会搞砸。请注意,您始终可以在需要时将 'routeReuseStrategy' 设置为 true。