2017-10-09 1 views
6

J'ai fait des recherches sur le rechargement d'une route Angular 4+ et il semble que la méthode préférée consiste à écouter les changements de paramètres d'URL dans le composant et à les réinitialiser le composant là à la place. Le problème que je rencontre est d'essayer de trouver une approche DRY (ne vous répétez pas) pour que cela fonctionne à travers plusieurs composants, quand l'URL serait identique (y compris les paramètres). Dans AngularJS c'était simple avec UI-routeur.Recharger la route angulaire 4+ avec le même paramètre d'URL

utilisation:

J'ai un panneau de notification qui peut « flotter » au-dessus de toute voie, lorsqu'une notification est cliqué, il doit aller au contenu, il concerne - cela peut être beaucoup de différents types de contenu.

Par exemple: /posts/:id ou /groups/:id ou /users/:id

Si l'utilisateur est à la recherche déjà à ce contenu, il ne se recharge pas et actualiser pour refléter le message de la notification. I.e "John Doe a commenté votre publication" (l'utilisateur pourrait consulter une version obsolète de ce message) ou "Jane Doe a accepté votre demande de rejoindre un groupe" (l'utilisateur pourrait consulter la vue de l'invité de ce groupe).

J'ai regardé en utilisant window.location.reload() en détectant que l'itinéraire est le même, et qui fonctionne, mais il est hautement indésirable en raison de la surcharge provoque (réinitialisation angulaire, contrôle auth, rebranchement socket, etc).

Toutes les suggestions seraient grandement appréciées!

Répondre

0

Il n'y a aucun moyen de simplement recharger l'itinéraire lorsque rien n'a changé dans l'URL. En effet, les seules options que vous avez sont window.location.reload() et en écoutant les paramètres changent.

Pour la deuxième option, vous pouvez créer un service générique qui surveillera les modifications de l'argument id dans la chaîne de requête. Appelons-le IdWatchService et il ressemblerait à quelque chose comme ceci:

@Injectable() 
export class IdWatchService { 
    constructor(private route: ActivatedRoute) { 
    } 

    get idChange(): Observable<number | undefined> { 
    return this.route.queryParams.map(p => p['id'] as number | undefined).distinctUntilChanged(); 
    } 
} 

vous pouvez ajouter ce service à la liste des providers sur les composants qui doivent réagir aux changements (PostsComponent, GroupsComponent, etc.). Et enfin, vous pouvez l'injecter aux ces mêmes composants et abonnez-vous à la idChange observable:

@Component({ 
    templateUrl: './posts.component.html', 
    providers: [ 
    IdWatchService 
    ] 
}) 
export class PostsComponent { 
    constructor(idWatchService: IdWatchService) { 
    idWatchService.idChange.subscribe(id => { 
     // Load data for the new ID and refresh the view 
    }); 
    } 
} 
+1

Je pense que ce n'est pas ce qui a été demandé. Citation de la question> quand l'URL serait identique (y compris les paramètres) – asmmahmud

+0

@asmmahmud En effet, je vois. Cependant, il n'y a aucun moyen de le faire sans 'window.location.reload()'. J'ai légèrement modifié ma réponse pour clarifier cela. –

0

J'ai fait face le même scénario (très similaire de cas d'utilisation) de retour dans angulaire 2. Comme d'autres réponses ont dit, je trouvai n'a pas été construit de manière angulaire pour le faire (peut-être l'hypothèse de base est qu'un tel cas devrait être résolu simplement en écoutant les changements dans les paramètres).

Comme vous, je ne voulais pas réécrire mon code, j'ai donc utilisé une solution différente, c'est un peu plus hacky, mais cela a fonctionné sans trop de changements.

La solution que j'ai utilisée était de créer une route factice sous le même niveau de hiérarchie où vous devez recharger la page. Dans la route fictive j'ai utilisé un composant Dummy qui reçoit dans les paramètres de route des données qui décrivent la route suivante (celle que nous voulons recharger) et les paramètres que je devrais passer (comme id vous J'ai mentionné) et puis j'ai utilisé la classe Rounter injectée avec la méthode de navigation pour aller à cette route.

Je pense que cette solution sera beaucoup plus efficace que l'utilisation de window.reload et qu'elle est assez simple à écrire. (Je ne peux pas copier cet exemple de code parce que je n'ai pas accès à ce code)

-2

window.location.reload();

C'est un travail pour moi.

+3

cela va rafraîchir la page entière – uriz

0

Dans ce cas, votre itinéraire ne change pas, seuls vos paramètres changent.

Pour résoudre ce problème, vous devez vous abonner aux paramètres ActivatedRoute.

export class MyClass implements OnInit { 
    constructor(private activatedRoute: ActivatedRoute) { 
     this.activatedRoute.params.subscribe((params)=>{ 
      console.log('updatedParams', params); 
     }); 
    } 
} 
0

je faisais face au même problème avec la section de notification dans l'en-tête J'ai résolu ce problème avec DoCheck

import { Component, DoCheck } from '@angular/core'; 

En classe implémente l'interface DoCheck

export class HeaderComponent implements DoCheck { 

Ensuite, utilisez Méthode ngDoCheck() et vérifiez si la valeur de la variable change, elle sera affichée dans la zone de notification

ngDoCheck() { 
    // check if values changes 
} 
0

Par this.router.url vous trouverez l'adresse de la page courante. Que d'utiliser la navigation du routeur comme avec queryParames. Voici l'exemple du passage de queryParams en tant que page pour la pagination. Vous pouvez utiliser une approche similaire.

const url = this.router.url.split('?')[0]; // this will remove previous queryparms 
    this.router.navigate([url], { queryParams: { page: $event } });