Estou chamando router.navigate
na mesma página com alguns parâmetros de string de consulta. Nesse caso, ngOnInit()
não liga. É por padrão ou preciso adicionar mais alguma coisa?
Estou chamando router.navigate
na mesma página com alguns parâmetros de string de consulta. Nesse caso, ngOnInit()
não liga. É por padrão ou preciso adicionar mais alguma coisa?
Respostas:
Você pode injetar o ActivatedRoute
e assinarparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
O roteador apenas destrói e recria o componente quando navega para uma rota diferente. Quando apenas parâmetros de rota ou parâmetros de consulta são atualizados, mas a rota é a mesma, o componente não será destruído e recriado.
Uma maneira alternativa de forçar o componente a ser recriado é usar uma estratégia de reutilização personalizada. Veja também Roteador Angular2 2.0.0 não recarregando componentes quando o mesmo url é carregado com parâmetros diferentes? (não parece haver muita informação disponível ainda como implementá-lo)
Você pode ajustar o reuseStrategy no Roteador.
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
ao objeto de configuração assim: RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
. Não posso falar por nenhuma outra versão Angular, entretanto.
Eu usei o seguinte e funcionou.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
Você provavelmente precisa recarregar a página? Esta é a minha solução: mudei o @NgModule (no arquivo app-routing.module.ts no meu caso):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
No seu método de navegação,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
Eu tive o mesmo problema, além disso, recebi o aviso:
did you forget to call `ngZone.run()`
Este site forneceu a melhor solução:
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]));
}
Esse problema provavelmente está vindo do fato de que você não está encerrando suas assinaturas usando ngOnDestroy. Aqui está como fazer.
Traga a seguinte importação de assinatura rxjs.
import { Subscription } from 'rxjs/Subscription';
Adicione OnDestory à sua importação Angular Core.
import { Component, OnDestroy, OnInit } from '@angular/core';
Adicione OnDestory à sua classe de exportação.
export class DisplayComponent implements OnInit, OnDestroy {
Crie uma propriedade de objeto com um valor de Subscription from rxjs em sua classe de exportação para cada assinatura no componente.
myVariable: Subscription;
Defina o valor de sua assinatura para MyVariable: Subscriptions.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Então, logo abaixo do ngOninit, coloque o gancho do ciclo de vida ngOnDestory () e coloque sua instrução de cancelamento de assinatura para sua assinatura. Se você tiver vários, adicione mais
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
vez de ngOnDestroy
eu também ;-)
Aqui está uma coleção das melhores ideias nesta página com mais informações
Solução 1 - Use a assinatura do params:
Tutorial: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Documentos: https://angular.io/api/router/ActivatedRoute#params
Em cada um dos seus componentes de roteamento que usam variáveis param, incluem o seguinte:
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();
}
}
Alguns problemas comuns com esse código são que as assinaturas são assíncronas e podem ser mais difíceis de lidar. Além disso, você não pode se esquecer de cancelar a assinatura do ngOnDestroy, ou coisas ruins podem acontecer.
O bom é que essa é a maneira mais documentada e comum de lidar com esse problema. Também há uma melhoria de desempenho ao fazer isso dessa maneira, já que você está reutilizando o modelo em vez de destruir e recriar cada vez que visitar uma página.
Solução 2 - shouldReuseRoute / onSameUrlNavigation:
Documentos: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
Documentos: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
Documentos: https://angular.io/api/router/ActivatedRouteSnapshot#params
Encontre onde RouterModule.forRoot
está localizado em seu projeto (normalmente encontrado em app-routing.module.ts ou app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
Em seguida, em AppComponent, adicione o seguinte:
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;
};
// ...
}
// ...
}
Por último, em seus componentes de roteamento, você agora pode lidar com variáveis de parâmetros como este:
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;
// ...
}
// ...
}
Os problemas comuns com essa solução é que ela não é comum. Além disso, você está alterando o comportamento padrão da estrutura Angular, para que possa enfrentar problemas que as pessoas normalmente não encontrariam.
O bom é que todo o seu código é síncrono e mais fácil de entender.
Considere mover o código que você tinha em ngOnInit para ngAfterViewInit. Este último parece ser chamado na navegação do roteador e deve ajudá-lo neste caso.
Quando você deseja navegar no roteador na mesma página e deseja chamar ngOnInit (), você faz assim, por exemplo,
this.router.navigate (['categoria / lista', categoria]) .então (() => window.location.reload ());