路由器导航在同一页时不调用 ngOnInit

我用一些查询字符串参数在同一个页面上调用 router.navigate。在这种情况下,ngOnInit()不调用。是默认设置还是需要添加其他内容?

139814 次浏览

您可以注入 ActivatedRoute并订阅 params

constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}

路由器只有在导航到不同路由时才会销毁和重新创建组件。如果只更新路由参数或查询参数,但路由是相同的,则不会销毁和重新创建组件。

强制重新创建组件的另一种方法是使用自定义重用策略。另请参阅 Angular2路由器2.0.0不重新加载组件时,相同的网址加载不同的参数?(似乎没有太多可用的信息,但如何实现它)

在创建实例时将调用 NgOnInit 一次。对于同一实例,不会再次调用 NgOnInit。为了调用它,有必要销毁创建的实例。

考虑将 ngOnInit 中的代码移动到 ngAfterViewInit 中。 后者似乎是在路由器导航中调用的,在这种情况下应该会对您有所帮助。

您可以调整路由器上的重用策略。

constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}

这个问题可能是由于您没有使用 ngOnDestroy 终止订阅这一事实造成的。下面是如何完成这项工作的方法。

  1. 引入以下 rxjs 订阅导入。 import { Subscription } from 'rxjs/Subscription';

  2. 将 OnDestory 添加到角核心导入。 import { Component, OnDestroy, OnInit } from '@angular/core';

  3. 将 OnDestory 添加到导出类中。 export class DisplayComponent implements OnInit, OnDestroy {

  4. 为组件上的每个订阅在导出类下的 rxjs 中创建一个值为 Subscrition 的对象属性。 myVariable: Subscription;

  5. 将您的订阅的值设置为 MyVariable: 订阅。 this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});

  6. 然后在 ngOninit 的右下方放置 ngOnDestory ()生命周期挂钩,并为订阅输入取消订阅声明。如果有多个,则添加更多 破坏(){ 取消订阅() ; }

您可能需要重新加载页面吗?这是我的解决方案: 我修改了 @ NgModule(在我的案例中是 < em > app-route.module.ts 文件) :

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

当您希望路由器在同一个页面上导航并调用 ngOnInit ()时,

导航([‘种类/列表’,种类]) . then (() = > window.location.reload ()) ;

为路由数组中的同一组件创建不同的路径。

康斯特路线: 路线 = [{ 路径: “应用程序”, 组件: MyComponent }, { 路径: “ app-reload” 组件: MyComponent }];

如果当前的 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: 应该重用路由/onSameUrlNavigation.conSameUrlNavigation.conSameUrlNavigation.conSameUrlNavige.com:

医生: 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 框架的默认行为,因此您可能会遇到人们通常不会遇到的问题。

好的方面是,所有代码都是同步的,并且更容易理解。

角度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}});

这是最好的解决方案为路由器导航时不调用 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']);

这应该工作,应该只用于特殊情况。当你不需要在重定向之后导航很多的时候,你可以使用这个,否则有时候会出问题。请注意,您总是可以在需要时将“ routeReuseStrategy”设置为 true。

解决方案可以订阅您的路由器事件。

导入 RouterNavigationEnd

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

在构造函数中初始化路由器。

constructor(router: Router) {

在构造函数中订阅路由器事件。

        this.router.events.subscribe((ev) => {
if (ev instanceof NavigationEnd) {
//do something
}
});

我发现开发人员有时候需要为每个 router.guide 编写通用代码,如果它在 app.component.ts或任何共享组件中,这就是答案。