it-swarm.com.de

Neigungsänderung von Winkel 2 bei Parameteränderung

Ich schreibe gerade meine erste Angular 2-Anwendung . Ich habe eine OverviewComponent, die die folgende einfache Vorlage hat:

<div class="row">
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
  <div class="col-lg-4">
    <app-list></app-list>
  </div>
</div>

beim Zugriff auf die URL / leitet mein Router mich an /overview weiter, der dann eine Karte in den Router-Ausgang lädt. Der <app-list> verfügt über eine Liste anklickbarer Elemente, die dazu führen, dass anstelle der App-Komponente ein <app-detail> angezeigt wird. Dazu übergebe ich die ID der verweisenden Json-Datei in der URL wie folgt: /details/:id (in meinen Routen).

Alle oben genannten Funktionen funktionieren völlig in Ordnung. Wenn ich jetzt auf eines der Listenelemente klicke, werden die Details angezeigt. ABER wenn ich ein anderes Listenelement auswähle, ändert sich die Ansicht nicht in die neuen Details. Die URL ändert sich, der Inhalt wird jedoch nicht erneut geladen. Wie kann ich eine Reinitialisierung der DetailComponent erreichen?

28
hGen

In der ersten endgültigen Version ist dies behoben. 

Achten Sie einfach darauf, den Zustand der Komponente bei Änderungen des Parameters korrekt zurückzusetzen

this.route.params.subscribe(params => {
    this.param = params['yourParam'];
    this.initialiseState(); // reset and set based on new parameter this time
});
29
gpanagopoulos

Sie können die routeReuseStrategy direkt auf Komponentenebene ändern:

constructor(private router: Router) {

      // force route reload whenever params change;
      this.router.routeReuseStrategy.shouldReuseRoute = () => false;

}

Ebenso kann die Wiederverwendungsstrategie global geändert werden. 

Dies ist nicht unbedingt ein direktes Problem für Sie, aber diese Frage ist das erste Suchergebnis für " angle 2 reload url, wenn sich die Abfrageparameter ändern ". Dies könnte die nächste Person vor dem Durchsuchen der Probleme mit github retten.

54
Nik

Eine weitere Alternative, die hier hinzugefügt werden sollte, ist die Bereitstellung einer RouteReuseStrategy zu Ihrem Modul.

providers: [
  {
    provide: RouteReuseStrategy,
    useClass: AARouteReuseStrategy
  }
]

Das Standardverhalten des Routers ist die Wiederverwendung der Route, wenn die Konfiguration identisch ist (dies ist der Fall, wenn nur der Parameter: id in dieser Frage geändert wird). Wenn Sie die Strategie so ändern, dass die Route nicht wiederverwendet wird, wird die Komponente erneut geladen, und Sie müssen keine Routenänderungen in der Komponente abonnieren.

Eine Implementierung der RouteReuseStrategy könnte folgendermaßen aussehen:

export class AARouteReuseStrategy extends RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  store(route: ActivatedRouteSnapshot, handle: {}): void {

  }
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  retrieve(route: ActivatedRouteSnapshot): {} {
     return null;
 }
 shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
   return false; // default is true if configuration of current and future route are the same
 }
}

Ich habe auch hier etwas darüber geschrieben:

https://pjsjava.blogspot.no/2018/01/winklig-components-not-reloading-on.html

8

Ich weiß nicht, ob es eine Antwort auf dieses Problem gibt, die der von mir hier vorgeschlagenen ähnelt, also werde ich es trotzdem tun:

Es gelang mir, ein "falsches" Nachladen auf folgende Weise zu erreichen.

Was ich im Grunde gemacht habe, ist das Erstellen einer Komponente, die mich zu der "echten" Komponente umleitet, die ich verwenden möchte:

@Component({
  selector: 'camps-fake',
  template: ''
})
export class FakeComponent implements OnInit {

  constructor(private _router:Router,
              private _route:ActivatedRoute)
  { }

  ngOnInit() {
    let id:number = -1;
    this._route.params.forEach((params:Params) => {
      id = +params['id'];
    });

    let link:any[] = ['/details', id];
    this._router.navigate(link);
  }

}

Wenn Sie also ein Listenelement auswählen, navigiert der Router zu /fake/:id, wodurch nur die ID aus der URL extrahiert und zur "echten" Komponente navigiert wird.

Ich weiß, dass es einen einfacheren oder schickeren Weg gibt, aber ich denke, dass diese Lösung gut funktioniert, da die Fälschung nicht wirklich auffällt. Lediglich das "Blinken" beim Neuladen der Seite ist ein negativer Aspekt, aber soweit mein CSS-Wissen reicht, könnte dies einen Übergang bedeuten.

7
hGen

Ist es möglich, Änderungen in den empfangenen Parametern zu erkennen, lade ich die Informationen in meinem Fall mit einer Auflösung, sodass ich den Parameter nicht benötige (nur erkennen, wenn er sich ändert). Dies ist meine endgültige Lösung:

public product: Product;
private parametersObservable: any;

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.parametersObservable = this.route.params.subscribe(params => {
    //"product" is obtained from 'ProductResolver'
    this.product = this.route.snapshot.data['product'];
  });
}

//Don't forget to unsubscribe from the Observable
ngOnDestroy() {
  if(this.parametersObservable != null) {
    this.parametersObservable.unsubscribe();
  }
}
3
Alexis Gamarra
this.route.paramMap.subscribe(params => {
  //fetch your new parameters here, on which you are switching the routes and call ngOnInit()
  this.ngOnInit();
 });

Sie müssen nur ngOnInit () aus der paramMap aufrufen und die gesamte Seite wird mit den neu geladenen Daten initialisiert.

2
cyperpunk

Ich löste es mithilfe von event. Wenn die untergeordnete Komponente einen neuen Link sendet und ein Ereignis auslöst, kann das übergeordnete Element die Änderung finden und eine Reload-Funktion aufrufen, die die erforderlichen Daten erneut lädt. Eine weitere Option ist das Abonnieren zu den route-Parametern und gefunden, wenn sie sich ändern Aber ich denke, dass die Jungs von angle2 überlegen sollten, ob sie der router.navigate-Funktion Parameter hinzufügen, die das Neuladen erzwingen können. (forceReload = true)

2
user3728728

Importiere Router in dein Angular 7 Projekt.

import { Router } from '@angular/router';

Erstellen Sie ein Objekt des Routers

constructor(private router: Router) {

}

Verwenden Sie routeReuseStrategy, um Änderungen an Routerparametern zu erkennen

ngOnInit() {
    this.router.routeReuseStrategy.shouldReuseRoute = () => {
      // do your task for before route

      return false;
    }
}
2
Abhisek Dutta

Dies wird derzeit nicht direkt unterstützt. Siehe auch https://github.com/angular/angular/issues/9811

Was Sie tun können, ist so etwas

<div *ngIf="doShow" class="row">
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
  <div class="col-lg-4">
    <app-list></app-list>
  </div>
</div>
doShow:boolean: true;

constructor(private _activatedRoute: ActivatedRoute, private _router:Router, private cdRef:ChangeDetectorRef) {
  _router.routerState.queryParams.subscribe(
    data => {
      console.log('queryParams', data['st']); 
      this.doShow = false;
      this.cdRef.detectChanges();
      this.doShow = true;
  });
}

(nicht getestet)

1

hoffe das wird helfen.

constructor(private router: Router){
 // override the route reuse strategy

 this.router.routeReuseStrategy.shouldReuseRoute = function(){
    return false;
 }

 this.router.events.subscribe((evt) => {
    if (evt instanceof NavigationEnd) {
       // trick the Router into believing it's last link wasn't previously loaded
       this.router.navigated = false;
       // if you need to scroll back to top, here is the right place
       window.scrollTo(0, 0);
    }
});

}
0