angular - Hur kan jag ändra en specifik, intern ruttparameter i Angular2


Jag bygger en kalender som kan visa olika typer av data. Följande exempel förklarar min URL-struktur, tror jag:

  • todo/2017/01/01 en dagsvy av att-göra-listor
  • birthdays/2017/01/01 en dagsvy över födelsedagar
  • todo/2017/01 en månadsöversikt över att-göra-listor
  • birthdays/2017/01 en månadsöversikt över födelsedagar
  • todo/2017 en årsöversikt över todo-uppgifter
  • birthdays/2017 en årsvisning av födelsedagar

Hittills har jag kunnat skicka in ett Date-objekt och omdirigera via

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

Problemet är att jag vill kunna navigera från todo/2017/01/01 => birthdays/2017/01/01 ELLER todo/2017/01 => birthdays/2017/01.

Så jag kan inte skicka in datumparametrarna eftersom vissa kanske inte finns beroende på vilken vy jag befinner mig i.

Så hur kan jag bara byta ut en enda intern parameter och omdirigera?

Något som

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

Annars måste jag skriva ett komplicerat switch-sats för varje möjlig kombination.

Svar #1

Du kan uppnå detta via den inbyggda ActivatedRoute-tjänsten, din "one-stop-shop för ruttinformation", som det heter i dokumentationen.

Först behöver du injicera tjänsten i din komponents konstruktor. Förutsatt att du har en Todo-komponent och en Birthday-komponent, skulle konstruktorn i båda fallen se ut så här:

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

Sedan, i din ngOnInit()-funktion, behöver du prenumerera på din ActivatedRoute-instans url-egenskap, som är en Observable:

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

Anledningen till att din komponentrutt tillhandahålls som ett Observable är att den under din komponents livscykel kan ta emot flera olika rutter. Som i ditt fall "/todo/2017" eller "todo/2017/01" osv. Din komponent kommer bara att skapas en gång, ngOnInit() kommer också bara att anropas en gång, men genom att prenumerera på ActivatedRoute.url-observable kommer du alltid att få meddelanden om den aktuella rutten.

Ovanstående kodblock fyller en array med alla delar av URL:en från den aktiverade rutten utom den första, vilket ger dig alla överlämnade parametrar förutom den initiala "/todo"- eller "/birthday"-delen.

Nu kan du navigera till den andra komponenten genom att helt enkelt lägga till den erforderliga sökvägen i början av denna parameterarray, såsom:

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

Här är hela koden för Todo-komponenten och dess mall:

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>

Födelsedagskomponenten skulle se nästan identisk ut. Ovanstående gör att du kan gå fram och tillbaka mellan "/todo/2017/1/3" och "/birthday/2017/1/3" och även mellan "/todo/2017" och "/birthday/2017" osv. - utan att ställa in några specifika routningsregler.

En parentes: för valfria parametrar är det vanligtvis bättre att inte inkludera dem i URL-sökvägen, utan att tillhandahålla dem som ett valfritt ruteobjekt - se denna del av dokumentationen.

Relaterade artiklar