2017-10-09 2 views
6

Ich habe einige Nachforschungen über das Nachladen einer Angular 4+ Route angestellt, und es sieht so aus, als ob die bevorzugte Methode darin besteht, URL-Parameteränderungen innerhalb der Komponente zu hören und neu zu initialisieren die Komponente dort stattdessen.Angular 4+ Route mit demselben URL-Parameter neu laden

Das Problem, das ich habe, ist in der Suche nach einem DRY (nicht wiederholen) Ansatz, um dies über mehrere Komponenten funktionieren, wenn die URL identisch wäre (einschließlich der Parameter). In AngularJS war dies mit UI-Router einfach.

Anwendungsfall:

Ich habe ein Benachrichtigungsfeld, die „schweben“ über jeder Route kann, wenn eine Benachrichtigung geklickt wird es auf den Inhalt gehen muss es betrifft - diese unterschiedlichen viele sein können Arten von Inhalt.

Zum Beispiel: /posts/:id oder /groups/:id oder /users/:id

Wenn der Benutzer bereits an diesem Inhalt sucht sie nicht und nicht nachladen aktualisieren Sie die Nachricht der Mitteilung zu reflektieren. "John Doe hat Ihren Beitrag kommentiert" (der Nutzer könnte sich eine veraltete Version dieses Beitrags ansehen) oder "Jane Doe hat Ihre Anfrage akzeptiert, einer Gruppe beizutreten" (der Nutzer könnte sich die Gastansicht dieser Gruppe ansehen).

habe ich in aussehen window.location.reload() Verwendung bei der Erkennung, dass die Route das gleiche ist, und das funktioniert, aber es ist höchst unerwünscht aufgrund des Kopf es (Winkel neu initialisieren, Auth Scheck, Buchse Wiederverbindung usw.) verursacht.

Alle Vorschläge würden sehr geschätzt werden!

Antwort

0

Es gibt keine Möglichkeit, die Route einfach neu zu laden, wenn sich an der URL nichts geändert hat. In der Tat, die einzigen Optionen, die Sie haben, sind window.location.reload() und hören die Parameter ändern.

Für die zweite Option können Sie einen generischen Dienst erstellen, der die Änderungen des id-Arguments in der Abfragezeichenfolge überwacht. Nennen wir es IdWatchService und es würde wie folgt aussehen:

@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(); 
    } 
} 

Dann Sie diesen Dienst in die Liste der providers auf die Komponenten, die auf die Veränderungen reagieren müssen hinzufügen (PostsComponent, GroupsComponent, etc.). Und schließlich, können Sie es auf die die gleichen Komponenten injizieren können und abonnieren Sie den idChange beobachtbar:

@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

Ich denke, das ist nicht das, was gefragt wurde. Zitat aus der Frage> Wenn die URL identisch wäre (einschließlich der Parameter) – asmmahmud

+0

@asmmahmud In der Tat, ich sehe. Dies ist jedoch ohne 'window.location.reload()' nicht möglich. Ich habe meine Antwort ein wenig modifiziert, um das klarzustellen. –

0

ich das gleiche Szenario konfrontiert (sehr ähnlich Anwendungsfall) zurück in Winkel 2. Wie andere Antworten gesagt, fand ich dort war nicht in eckigen dazu gebaut (vielleicht die Rahmen-Annahme ist, dass solcher Fall nur durch das Hören auf Änderungen in den Params gelöst werden sollte).

Wie Sie wollte ich nicht meinen Code umschreiben, also habe ich eine andere Lösung verwendet, es ist ein bisschen hacky, aber es funktionierte ohne viel Änderungsbedarf.

Die Lösung, die ich verwendet habe, war eine Dummy-Route unter der gleichen Ebene der Mietverwaltung, wo Sie die Seite neu laden müssen. In der Dummy-Route habe ich eine DummyComponent verwendet, die in der Route params-Daten empfängt, die beschreiben, was die nächste Route war (die, die wir neu laden wollen) und welche Params ich an sie weitergeben sollte (wie id you) habe ich erwähnt) und dann habe ich die injected Rounter-Klasse mit der navigate-Methode benutzt, um auf diese Route zu gehen.

Ich denke, diese Lösung wird viel effizienter sein als window.reload und es ist ziemlich einfach zu schreiben. (Ich kann dieses Codebeispiel nicht kopieren, da ich keinen Zugriff auf diesen Code habe)

-2

window.location.reload();

Das ist Arbeit für mich.

+3

Dies wird die gesamte Seite aktualisieren – uriz

0

In diesem Fall ändert sich Ihre Route nicht, nur Ihre Parameter ändern sich.

Um dieses Problem zu lösen, müssen Sie die ActivatedRoute-Parameter abonnieren.

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

Ich war mit der Benachrichtigungsabschnitt vor dem gleichen Problem im Header ich dieses Problem mit DoCheck gelöst haben

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

In der Klasse der DoCheck Schnittstelle implementieren

export class HeaderComponent implements DoCheck { 

Dann nutzen ngDoCheck() -Methode und überprüfen, ob sich der Wert der Variablen ändert, wird dies in Ihrem Benachrichtigungsbereich

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

Durch this.router.url erhalten Sie URL der aktuellen Seite. Verwenden Sie dann die Router-Navigation wie bei queryParames. Das folgende Beispiel zeigt die Übergabe von queryParams als Seite für die Paginierung. Sie können ähnliche Ansätze verwenden.

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