Я звоню 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, который не перезагружает компоненты, когда один и тот же 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.
Я использовал следующее, и это сработало.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
Возможно, вам нужна перезагрузка страницы? Это мое решение: я изменил @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}});
У меня была такая же проблема, кроме того, я получил предупреждение:
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 {
Создайте свойство объекта со значением Subscription from rxjs в вашем классе экспорта для каждой подписки на компонент.
myVariable: Subscription;
Установите для своей подписки значение MyVariable: Subscriptions.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Затем прямо под ngOninit поместите крючок жизненного цикла ngOnDestory () и вставьте оператор отказа от подписки для своей подписки. Если у вас их несколько, добавьте еще
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
вместо ngOnDestroy
себя ;-)
Вот коллекция лучших идей на этой странице с дополнительной информацией
Решение 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 по умолчанию, чтобы вы могли столкнуться с проблемами, с которыми обычно не сталкивались бы люди.
Хорошо то, что весь ваш код синхронный и более понятный.
Подумайте о переносе кода, который у вас был в ngOnInit, в ngAfterViewInit. Последний, похоже, вызывается при навигации по маршрутизатору и должен помочь вам в этом случае.
Если вы хотите, чтобы маршрутизатор перемещался на той же странице и хотите вызвать ngOnInit (), вам это нравится, например,
this.router.navigate (['категория / список', категория]) .then (() => window.location.reload ());