Я вызываю router.navigate
на той же странице с некоторыми параметрами строки запроса. В этом случае ngOnInit()
не звонит. Это по умолчанию или мне нужно что-то еще добавить?
Router Navigate не вызывает ngOnInit, когда та же страница
Ответы (12)
Вы можете ввести ActivatedRoute
и подписаться на params
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
Маршрутизатор уничтожает и воссоздает компонент только тогда, когда он переходит на другой маршрут. Когда обновляются только параметры маршрута или параметры запроса, но маршрут остается тем же, компонент не будет уничтожен и воссоздан.
Альтернативный способ принудительно воссоздать компонент - использовать настраиваемую стратегию повторного использования. См. Также Маршрутизатор Angular2 2.0.0 не перезагружает компоненты, когда один и тот же URL-адрес загружен с разными параметрами? (пока нет информации о том, как это реализовать)
Вы можете настроить 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.
- person Hildy; 19.09.2018
/user/3
и /user/5
рассматриваются как равные. Но может я что-то не так понял.
- person Chuck; 22.02.2021
Угловой 9
Я использовал следующее, и это сработало.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
- person Halfist; 18.08.2020
Возможно, вам нужна перезагрузка страницы? Это мое решение: я изменил @NgModule (в моем случае в файле app-routing.module.ts):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
Вот коллекция лучших идей на этой странице с дополнительной информацией
Решение 1. Используйте подписку на параметры:
Учебное пособие: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Документы: https://angular.io/api/router/ActivatedRoute#params
В каждом из ваших компонентов маршрутизации, которые используют переменные param, включают следующее:
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;
};
// ...
}
// ...
}
Наконец, в ваших компонентах маршрутизации вы теперь можете обрабатывать переменные param следующим образом:
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, чтобы вы могли столкнуться с проблемами, с которыми обычно не сталкивались бы люди.
Хорошо то, что весь ваш код синхронный и более понятный.
На вашем методе навигации,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
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]));
}
Эта проблема, вероятно, возникает из-за того, что вы не прекращаете свои подписки с помощью ngOnDestroy. Вот как это сделать.
Принесите следующий импорт подписки rxjs.
import { Subscription } from 'rxjs/Subscription';
Добавьте OnDestory в свой Angular Core Import.
import { Component, OnDestroy, OnInit } from '@angular/core';
Добавьте OnDestory в свой экспортный класс.
export class DisplayComponent implements OnInit, OnDestroy {
Создайте свойство объекта со значением «Подписка из rxjs» в своем классе экспорта для каждой подписки на компонент.
myVariable: Subscription;
Установите для подписки значение MyVariable: Subscriptions.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Затем прямо под ngOninit поместите перехватчик жизненного цикла ngOnDestory () и вставьте оператор отказа от подписки для своей подписки. Если у вас их несколько, добавьте еще
ngOnDestroy() { this.myVariable.unsubscribe(); }
ngOnDestory
вместо ngOnDestroy
;-)
- person Simon_Weaver; 22.02.2019
Создайте другой путь для того же компонента в массиве маршрутов.
константные маршруты: Routes = [{путь: "приложение", компонент: MyComponent}, {путь: "приложение-перезагрузка", компонент: MyComponent}];
Если текущий URL-адрес - «app», используйте для навигации «app-reload» и наоборот.
Подумайте о переносе кода, который у вас был в ngOnInit, в ngAfterViewInit. Последний, похоже, вызывается при навигации по маршрутизатору и должен помочь вам в этом случае.
Если вы хотите, чтобы маршрутизатор перемещался на той же странице и хотите вызвать ngOnInit (), вам это нравится, например,
this.router.navigate (['категория / список', категория]) .then (() => window.location.reload ());