web-dev-qa-db-fra.com

Recharger un composant avec différents paramètres de route dans angular4

J'utilise le routage angular2. Lorsque l'utilisateur ressaisit la valeur dans le champ de recherche et clique sur recherche, le même composant doit être rechargé, mais avec des paramètres de routage différents.

<button (click)="onReload()">Search</button>

onReload() {
this.router.navigate(['results',this.location]);
}

Ceci est mon chemin de route pour mes résultats

{ path:'results/:location', component:ResultsComponent}

Cette fonction modifie l'URL, mais ne réinitialise pas le composant.

Dans angularjs, ui-router je pourrais le réaliser comme ça.

$state.go($state.current, location, {reload: true});

Comment puis-je faire cela dans angular4?

6
CKA

Vous devez exécuter la logique d'initialisation dans la fonction de rappel d'abonnement dans la fonction de rappel d'abonnement du flux observable route.params.

Dans votre classe de composant

@Component({
  ...
})
export class MyComponent implements OnInit {

   myLocation:string;

   constructor(private route:ActivatedRoute) {}

   ngOnInit() {
     this.route.params.subscribe((params:Params) => {
        this.myLocation = params['location'];
        // -- Initialization code -- 
        this.doMyCustomInitialization();
     }
   }

   private doMyCustomInitialization() {
       console.log(`Reinitializing with new location value ${this.location}`);
   }
}

Dans un autre ordre d'idées, si vous devez résoudre les données en fonction de la valeur "emplacement", utilisez une protection de résolution qui résout les données avant la création du composant. Voir https://angular.io/guide/router#resolve-guard pour plus d'informations sur la résolution des gardes et le routage.

Voici un plunkr de travail. https://plnkr.co/edit/g2tCnJ?p=preview

2
JeanPaul A.

ÉDITÉ

La manière angulaire de demander au routeur de faire cela consiste à utiliser onSameUrlNavigation as of angular 5.1

Mais je devais résoudre ce problème différemment ( Stackblitz ), de subscribing à route events et en appelant un custom reInit method

L'astuce consiste à ajouter tous les abonnements au même objet, puis à vous désabonner UNIQUEMENT lorsque ngOnDestroy est appelé par angular. Le reste de vos vars de modèles passe alors du custom destroy method...

    public subscribers: any = {};

    constructor(private router: Router) {
    /** 
      * This is important: Since this screen can be accessed from two menu options 
      * we need to tell angular to reload the component when this happens.
      * It is important to filter the router events since router will emit many events,
      * therefore calling reInitComponent many times wich we do not want.
      */   
      this.subscribers._router_subscription = this.router.events.filter(evt => evt instanceof NavigationEnd).subscribe((value) => { 
        this.reInitComponent();
      });
    }

    reInitComponent() {
        this.customOnDestroy();
        this.customOnInit();
    }

    customOnInit() {
        // add your subscriptions to subscribers.WHATEVERSUB here
        // put your ngOnInit code here, and remove implementation and import 
    }

    customOnDestroy() {
      // here goes all logic to re initialize || modify the component vars  
    }

    /**
     * onDestroy will be called when router changes component, but not when changin parameters ;)
     * it is importatn to unsubscribe here
     */
     ngOnDestroy() {  
       for (let subscriberKey in this.subscribers) {
          let subscriber = this.subscribers[subscriberKey];
          if (subscriber instanceof Subscription) {
            subscriber.unsubscribe();
          }
        }
     }

Notez que si vous implémentez lifecylce hook ngOnInit, vous devez le supprimer et implémenter une méthode personnalisée comme dans l'exemple.

J'ai ajouté la méthode unsubscription à cause de this bug angulaire. Angular devrait en réalité se désabonner automatiquement de router.events lors de la destruction du composant, mais comme ce n'est pas le cas, si vous ne vous désabonnez pas manuellement, vous finirez par appeler des demandes http (par exemple) autant de fois que vous avez entré le composant.

2
FRECIA

https://angular-2-training-book.rangle.io/handout/routing/routeparams.html

Dans votre composant, vous devez vous abonner aux paramètres afin de détecter s'ils ont été modifiés.

1
Justin