2017-07-27 6 views
1

ich zur Zeit auf Router Ereignisse melde mich an den Titel meiner Seite zu ändern, wenn Routen zu ändern, wie somehrere Artikel aus this.router.events.subscribe Erste()

this.routerSub$ = this.router.events 
    .filter(event => event instanceof NavigationEnd) 
    .map(() => this.activatedRoute) 
    .map(route => { 
     while (route.firstChild) route = route.firstChild; 
     return route; 
    }) 
    .filter(route => route.outlet === 'primary') 
    .mergeMap(route => route.data) 
    .subscribe((event) => { 
     title = event['title'] 
      ? `${event['title']}` 
      : 'Default Title' 
     this.title.setTitle(title); 
    }); 

Mein Problem ist, dass bei bestimmten Szenarien, ich möchte den Titel auf einen Wert in URL (Teil einer Route) festlegen. Wie mache ich das hier? Ich weiß, dass ich die URL sowie Ereignisse nicht abonnieren kann, aber ich habe eine harte Zeit herauszufinden, was ich innen zuordnen kann.

Hier ist, was ich bin versucht

this.router.events 
     .filter(event => event instanceof NavigationEnd) 
     .map(() => { 
      return this.activatedRoute 
     }) 
     .switchMap(route => { 
     return route.data.combineLatest(route.url, (data, url) => { 
      return data['title'] ? `Title: ${data['title']}` : url.join(''); 
     }); 
    }) 

Auf der .switchMap Linie versagt, Route vom Typ ActivatedRoute ist, ist route.data vom Typ Object und der Fehler ich auf dem combineLatest () Linie ist

route.data.combineLatest ist keine Funktion

+0

Wollen Sie damit sagen, dass Sie sowohl 'events' und' url' beobachten wollen und irgendwie ihre Werte kombinieren? Wenn dies der Fall ist, könnte 'combineLatest' oder' withLatestFrom' helfen. –

+0

Danke, dass Sie mir den richtigen Weg gezeigt haben. Also erstelle ich grundsätzlich ein beliebiges Objekt und weise ihm Ereignisse und URLs als Requisiten zu? Vielleicht würde mir eine kleine Probe helfen –

Antwort

0

Wenn wir beiseite Winkel rou verlassen Bei den Details wollen Sie grundsätzlich Werte aus zwei verschiedenen Streams kombinieren. Es gibt mindestens ein paar Wege, wie man das macht.

Fall 1. Sie möchten den Titel immer dann aktualisieren, wenn einer der Streams ausstrahlt, und die neuesten Werte aus beiden Streams verwenden.

Verwendung combineLatest:

const getTitle$ = (activatedRoute) => { 
 
    return activatedRoute.url 
 
     .combineLatest(activatedRoute.data, (url, data) => { 
 
      return url + data; 
 
     }); 
 
}; 
 

 
const url = Rx.Observable.interval(400).take(3).map(x => `url_${x} `); 
 
const data = Rx.Observable.interval(200).take(6).map(x => `data_${x}`); 
 

 
getTitle$({ url, data }).subscribe(title => console.log(title));
<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/Rx.js"></script>

Fall 2. Sie möchten den Titel nur aktualisieren, wenn der url-Stream sendet, aber auch den neuesten Wert aus dem data-Stream abrufen.

Verwendung withLatestFrom:

const getTitle$ = (activatedRoute) => { 
 
    return activatedRoute.url 
 
     .withLatestFrom(activatedRoute.data, (url, data) => { 
 
      return url + data; 
 
     }); 
 
} 
 

 
const url = Rx.Observable.interval(400).take(3).map(x => `url_${x} `); 
 
const data = Rx.Observable.interval(200).take(6).map(x => `data_${x}`); 
 

 
getTitle$({ url, data }).subscribe(title => console.log(title));
<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/Rx.js"></script>

Wenn Sie begegnen, dass Ihr beobachtbaren keine dieser Operatoren enthält, versuchen, sie explizit zu importieren:

import 'rxjs/add/operator/combineLatest'; 
import 'rxjs/add/operator/withLatestFrom'; 

Update:

Um es präziser zu machen, hier ist ein Codebeispiel, das näher an der ursprünglichen Beispiel ist:

this.router.events 
    .filter(event => event instanceof NavigationEnd) 
    ... // <- route mapping and filtering skipped for brevity 
    .switchMap(route => { 
     return route.data.combineLatest(route.url, (data, url) => { 
      // make the title out of data and url 
      return data['title'] ? `Title: ${data['title']}` : url.join(''); 
     }); 
    }) 
    .subscribe(title => this.title.setTitle(title)); 
+0

Danke dafür aber ich bin noch ein wenig verloren. Ich muss mehrere Eigenschaften (Daten und URL) von this.activatedRoute in irgendeiner Weise erhalten. Ich versuche, combineLatest in diese Kette einzubauen und erhalte Type Errors. Muss ich ein const für Daten und ein const für URL erstellen und sie zusammenführen? –

+0

Können Sie näher erläutern, welche Art von Fehlern Sie erhalten und wie Ihr Code aussieht? 'data' und' url' der 'ActivatedRoute' scheinen beide Observable zu sein, jedoch mit unterschiedlichen Elementtypen. Sie können diese Werte so kombinieren, wie Sie es in der Projektionsfunktion benötigen, die Sie an 'combineLatest' übergeben, dh die Signatur würde etwa wie folgt aussehen: combineLatest (Observable , Observable , (UrlSegment [], Data) => String) '. –

+0

Ich habe den Code hinzugefügt, den ich verwende, und den Fehler, den ich bekomme –