2017-01-01 3 views
6

Ich erstelle einen Kalender, der verschiedene Arten von Daten anzeigen kann. Das folgende Beispiel erläutert meine URL-Struktur Ich denke:Wie kann ich einen bestimmten internen Routenparameter in Angular2 ändern?

  • todo/2017/01/01 eine Tagesansicht von todos
  • birthdays/2017/01/01 Tagesansicht Geburtstage
  • todo/2017/01 einen Monat Blick auf todos
  • birthdays/2017/01 einen Monat Ansicht Geburtstage
  • todo/2017 ein jahr ansicht von todos
  • birthdays/2017 ein jahr ansicht von geburtstagen

Bis jetzt, bis ich in einem Date Objekt passieren können müssen und Umleiten über

this.router.navigate([#HARDCODED# 'todo' #OR# 'birthday', year, ?month, ?day]) 

Das Problem ist, dass ich von todo/2017/01/01 =>birthdays/2017/01/01 OR todo/2017/01 =>birthdays/2017/01 navigieren können, will .

So kann ich nicht in den Datums Parameter übergeben, da einige existieren möglicherweise nicht abhängig von dem ich sehen bin.

Wie kann ich also nur einen einzigen, internen Parameter wechseln und umleiten?

So etwas wie

this.router.navigate(['todo', {ignoreTheRest: true}]) 

Ansonsten muss ich für jede mögliche Kombination eine komplizierte switch-Anweisung schreiben.

+0

Ich glaube, Sie können erreichen, was Sie wollen mit [optional Route Parameter] (https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters), auch ich habe noch nie zuvor getan. Ich werde es selbst ausprobieren müssen. – Timathon

+0

Optionale Routenparameter sind nicht der richtige Ansatz für Ihr Problem. András Szepesházi Antwort sollte es beheben. – Timathon

Antwort

3

Dies erreichen Sie über den integrierten Dienst ActivatedRoute, Ihr "One-Stop-Shop für Routeninformationen", wie sie in der documentation sagen.

Zuerst müssen Sie den Dienst in den Konstruktor Ihrer Komponente injizieren. Unter der Annahme, dass Sie eine Todo-Komponente eine ein Geburtstag Komponente haben, in jedem Fall würde der Konstruktor wie folgt aussehen:

constructor(private currentRoute: ActivatedRoute, private router: Router) { } 

Dann in Ihrer ngOnInit() Funktion, müssen Sie Ihre ActivatedRoute Instanz url Eigenschaft abonnieren, das ist ein beobachtbares:

ngOnInit() { 
    this.currentRoute.url 
     .subscribe(routeParts => { 
      this.periodArray = []; 
      for (let i = 1; i < routeParts.length; i++) { 
       this.periodArray.push(routeParts[i].path); 
      } 
     }); 
} 

Der Grund, warum die Komponente Route als beobachtbare vorgesehen ist, dass die Komponente des Lebenszyklus während es mehrere verschiedene Routen empfangen kann. Wie in deinem Fall "/ todo/2017" oder "todo/2017/01" etc. Deine Komponente wird nur einmal erstellt, die ngOnInit() wird auch nur einmal aufgerufen, aber durch das Abonnieren der ActivatedRoute.url beobachtbar wird immer über die aktuelle Route informiert.

Der obige Codeblock füllt ein Array mit allen außer dem ersten URL-Teil der aktivierten Route, der Ihnen alle übergebenen Parameter mit Ausnahme des ursprünglichen Segments "/ todo" oder "/ birthday" enthält.

Jetzt können Sie, indem Sie einfach auf die andere Komponente navigieren zu Beginn dieses Parameters Array den gewünschten Pfad hinzufügen, wie:

navigateBirthdays() { 
    this.periodArray.unshift('/birthday'); 
    this.router.navigate(this.periodArray); 
} 

Hier ist der vollständige Code für das Todo-Komponente und es ist Vorlage:

todo.component.ts

import { Component, OnInit } from '@angular/core'; 
import { ActivatedRoute, Router } from '@angular/router'; 

@Component({ 
    templateUrl: './todo.component.html', 
}) 
export class TodoComponent implements OnInit { 

    periodArray = []; 
    constructor(private currentRoute: ActivatedRoute, private router: Router) { } 

    ngOnInit() { 
    this.currentRoute.url 
     .subscribe(routeParts => { 
     this.periodArray = []; 
     for (let i = 1; i < routeParts.length; i++) { 
      this.periodArray.push(routeParts[i].path); 
     } 
     }); 
    } 

    navigateBirthdays() { 
    this.periodArray.unshift('/birthday'); 
    this.router.navigate(this.periodArray); 
    } 
} 

todo.component.html

<p> 
    List of Todo items for {{periodArray.join("-")}} 
</p> 
<button (click)="navigateBirthdays()">Show Birthday items</button> 

Die Geburtstagskomponente würde praktisch identisch aussehen. Das obige erlaubt es, zwischen "/ todo/2017/1/3" und "/ birthday/2017/1/3" und auch zwischen "/ todo/2017" und "/ birthday/2017" usw. hin- und herzugehen - ohne spezielle Routing-Regeln einzurichten.

Eine Randnotiz: Für optionale Parameter ist es normalerweise besser, sie nicht in den URL-Pfad aufzunehmen, sondern sie als optionales Routenobjekt bereitzustellen - siehe this section der Dokumentation.

+0

Stimmen Sie zu, das ist der direkte Ansatz. Eine Sache, die hinzugefügt werden muss, ist, dass wir uns in ngOnDestroy abmelden müssen, wie: '' ' Exportklasse TodoComponent implementiert OnInit, OnDestroy { subscriptions = []; ... ngOnInit() { const sub = diese.currentRoute.url .subscribe (...); this.subscription.push (sub); } ngOnDestroy() { this.subscription.forEach (sub => sub.unsubscribe()) } } '' ' – Timathon

+1

@Timathon aus der Dokumentation:„Wenn in einer Komponente zu einer beobachtbaren abonnieren Sie fast immer arrangieren, um abzubestellen, wenn die Komponente zerstört wird. Es gibt ein paar außergewöhnliche Observables, wo dies nicht notwendig ist. Die ActivatedRoute-Observablen gehören zu den Ausnahmen. " Aber sie fügen auch hinzu: "Fühlen Sie sich frei, sich abzumelden. Es ist harmlos und nie eine schlechte Praxis." :) –

+1

Ich erinnere mich vage daran, dass "es harmlos ist und niemals eine schlechte Praxis (sich abzumelden).", Aber kann sich einfach nicht erinnern, wo genau es herkommt. Jetzt weiß ich. Vielen Dank. – Timathon

Verwandte Themen