web-dev-qa-db-fra.com

Impossible de recharger/actualiser l'itinéraire actif

J'ai récemment mis à jour le nouveau RC3 et Router3alpha et il semble que certaines choses ont changé.

J'ai remarqué qu'un clic sur le lien d'un itinéraire actif n'entraîne plus le rechargement du composant. Comment puis-je obtenir ce comportement avec le nouveau routeur3?

Mon lien ressemble à

<a [routerLink]="['/link1']">Link1</a>

Et pour tester, j'ai simplement utilisé un nombre aléatoire dans ngOnInit:

export class LinkoneComponent implements OnInit 
{

    public foo: number;
    constructor() {}

    ngOnInit() 
    {
        this.foo = Math.floor(Math.random() * 100) + 1;
    }

}

Cela fonctionne très bien lorsque vous changez de route, mais un clic sur la route actuellement active n’entraîne pas de rechargement du composant.

25
TommyF

Ceci n'est actuellement pas pris en charge. Si seules les valeurs de paramètre changent mais que la route reste la même, le composant n'est pas recréé. 

Voir aussi https://github.com/angular/angular/issues/9811

Vous pouvez vous abonner à des paramètres pour être averti lorsque ceux-ci changent afin de réinitialiser l'instance du composant.

Voir aussi https://stackoverflow.com/a/38560010/217408

15
Günter Zöchbauer

Rechargement angulaire de la route actuelle 2-4

Pour moi, cette méthode fonctionne:

onRefresh() {
  this.router.routeReuseStrategy.shouldReuseRoute = function(){return false;};

  let currentUrl = this.router.url + '?';

  this.router.navigateByUrl(currentUrl)
    .then(() => {
      this.router.navigated = false;
      this.router.navigate([this.router.url]);
    });
  }

Vous pouvez attacher cette méthode à un événement click sur le composant actuel pour le recharger.

5
indreed

Depuis Angular 5.1, cela peut maintenant être fait en utilisant l'option de configuration onSameUrlNavigation Dans le routeur angulaire intégré. Il est assez simple à configurer et à démarrer, même si cela n’est pas évident dans la documentation.

La première chose à faire est de définir l'option dans votre app.routing.ts si vous en avez un ou le fichier dans lequel le routage de votre application est configuré.

Il existe deux valeurs possibles pour onSameUrlNavigation 'reload' ou false. La valeur par défaut est false, ce qui ne provoque rien lorsque le routeur est invité à accéder à la route active. Nous voulons définir cette valeur sur reload. Il est à noter que reload ne fait pas le travail de rechargement de la route, il ne fait que re-déclencher des événements sur le routeur auxquels nous devons ensuite nous connecter. 

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

Pour déterminer le moment où ces événements sont réellement déclenchés, vous devez spécifier l'option de configuration runGuardsAndResolvers sur votre itinéraire. Cela peut prendre trois valeurs ...

paramsChange - ne se déclenche que lorsque les paramètres de route ont changé, par exemple. où l'id dans /user/:id change

paramsOrQueryParamsChange - se déclenche quand un paramètre de route ou un paramètre de requête change. par exemple. la propriété id ou limit change dans /user/:id/invites?limit=10

always - Tirez toujours lorsque l'itinéraire est parcouru

Nous voulons spécifier toujours dans ce cas. Un exemple d'itinéraire est présenté ci-dessous.

export const routes: Routes = [
  {
    path: 'invites',
    component: InviteComponent,
    children: [
      {
        path: '',
        loadChildren: './pages/invites/invites.module#InvitesModule',
      },
    ],
    canActivate: [AuthenticationGuard],
    runGuardsAndResolvers: 'always',
  }
]

C'est votre routeur configuré. L'étape suivante consiste à gérer les événements de l'un de vos composants. Vous devrez importer le routeur dans votre composant, puis vous connecter aux événements. Dans cet exemple, j'ai adhéré à l'événement NavigationEnd qui est déclenché une fois que le routeur a terminé sa navigation d'un itinéraire à l'autre. En raison de la manière dont nous avons configuré l'application, celle-ci se déclenche même si vous essayez de naviguer vers l'itinéraire actuel.

export class InviteComponent implements OnInit {
  constructor(
    // ... your declarations here
    private router: Router,
  ) {
    // subscribe to the router events
    this.router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        this.initialiseInvites();
      }
    });
  }

  initialiseInvites() {
    // Set default values and re-fetch any data you need.
  }
}

La lourde tâche va dans la méthode initialiseInvites(), c’est là que vous réinitialisez les propriétés à leurs valeurs par défaut et extrayez les données des services pour ramener le composant à son état initial.

Vous devez répéter ce modèle pour chaque composant que vous souhaitez pouvoir recharger lorsque vous cliquez dessus ou actualiser via une forme de bouton d'actualisation, en vous assurant d'ajouter l'option runGuardsAndResolvers à chaque route dans le fichier de routage.

3
Simon McClive

Pour Angular 2 rc7 - routeur 3.0

Remplacez l'URL de base dans index.html par <script>document.write('<base href="/" />');</script>

2
supersonic

cela a fonctionné pour moi, pris de this :

redirectTo(uri) {
    this.router.navigateByUrl('/', {skipLocationChange: true}).then(() =>
    this.router.navigate([uri]));
  }

maintenant, vous pouvez utiliser comme: this.redirectTo(this.router.url);

1
simple_human

C'est le meilleur bidouillage que j'ai pu trouver pour contourner ce problème ennuyeux:

    var currentUrl = this.router.url;
    var refreshUrl = currentUrl.indexOf('someRoute') > -1 ? '/someOtherRoute' : '/someRoute';
    this.router.navigateByUrl(refreshUrl).then(() => this.router.navigateByUrl(currentUrl));

Cela fonctionne, mais ça reste un bidouillage et je déteste que l'équipe Angular n'ait pas fourni de méthode reload()

1
Serj Sagan
if (currentUrl.indexOf('/settings') > -1) {
    this.router.navigateByUrl('/communication').then(() => this.router.navigateByUrl('/settings'));
} else {
    this.router.navigate(['/settings']);
}
0