typescript - Angular 5 - Routing ändrar URL men navigerar inte


För närvarande har jag tre olika moduler:

  • App-modul -- med en tom array Rotkonfiguration
  • Hemmodul -- med en ''-vägkonfiguration för startsidans komponent för att söka efter en spelare
  • Spelarmodul för resultat -- visar resultatet av sökningen (antingen spelarstatistik eller felsida)

Nu i denna spelar-sökningsmodul har jag en spelar-sökningsresultatkomponent med underordnade komponenter. En av de underordnade komponenterna är en modal med en lista i. Om jag klickar på detta listaobjekt (spelare) bör det 'navigera' till föräldrakomponenten och uppdatera dess vy. Men det enda som uppdateras är URL:en.

Det finns en lösning med window.location.href(url) som laddar om sidan efter att navigeringsmetoden uppdaterar url:en. Men jag gillar inte genvägar.

Föräldrakomponenten ser ungefär ut så här:

export class PlayerSearchResultComponent implements OnInit, AfterViewInit {

 public isLoading = true;
  public searchValue: string;
  public playerResult: PlayerByPlayerTagType;
  public hasNoResultFound = false;
  public clanInfo: ClansByClantagType;

  constructor(private playerSearchService: PlayerSearchService,
              private activatedRoute: ActivatedRoute,
              private clanSearchService: ClanSearchService) {
  }

  ngOnInit(): void {
    this.activatedRoute.params.subscribe((params: Params) => {
      this.searchValue = params['playerId'];
    });
  }

  ngAfterViewInit() {
    this.playerSearchService.getPlayerByPlayerTag(this.searchValue).subscribe(player => {
        this.playerResult = player;
        if (!isUndefined(this.playerResult.clan)) {
          this.clanSearchService.getClanByClanTag(this.playerResult.clan.tag).subscribe((data: ClansByClantagType) => {
            this.clanInfo = data;
          });
        }
      }, () => {
        this.hasNoResultFound = true;
        this.isLoading = false;
      },
      () => this.isLoading = false);
  }
}

Och barnkomponenten:

export class ClanModalComponent {

  @ViewChild('childModal') childModal: ModalDirective;
  @Input() playerResult: PlayerByPlayerTagType;
  @Input() clanInfo: ClansByClantagType;


  constructor(private router: Router) {
  }

  open() {
    this.childModal.show();
  }

  memberSearch(member) {
    this.childModal.hide();
    this.router.navigate(['search/' + member.tag]);
  }

}

Spelarresultatmodulen ser ut så här:

const appRoutes: Routes = [
  {path: 'search/:playerId', component: PlayerSearchResultComponent}
];

@NgModule({
  declarations: [
   ...
  ],
  imports: [
    ...
    RouterModule.forChild(
      appRoutes
    )],
  providers: [
     ...
  ],
  exports: []
})
export class PlayerResultModule {
}

Svar #1

Så, för att ladda baserat på ruttparametern måste du prenumerera på ruttparametrar och sedan ladda datan. ngAfterViewInit kommer inte att bearbetas igen. Eftersom komponenten inte laddas igen efter ruttändring!

ngOnInit(): void {
    this.activatedRoute.params.subscribe((params: Params) => {
        this.searchValue = params['playerId'];
        this.playerSearchService
            .getPlayerByPlayerTag(this.searchValue)
            .subscribe(player => {
                this.playerResult = player;
                ...
                ...
            });
     }
}

Svar #2

//browser is already on /pathName/oldID, 
//this means our Routes are correct
 
 let newLocation = `/pathName/${newID}`;
 // override default re-use strategy
 this.router
    .routeReuseStrategy
    .shouldReuseRoute = function () {
        return false;
 };
 this.router
   .navigateByUrl(newLocation)
   .then(
   (worked) => {
        //works only because we hooked 
        //the routeReuseStrategy.shouldReuseRoute above
   },
   (error) => {
    debugger;
    }
 );

Jag har sett detta problem fler gånger än jag vill erkänna, det uppstår vanligtvis när jag har en föräldrakontainer som återanvänder en barnkomponent.

  • Föräldrarutten är xyz/ som standard. Allt laddas bra.
  • Förälder ändrar rutt till xyz/1 för att visa detaljer om personen med id 1
  • Föräldrasidan gör inget annat än att ändra URL:en.

Detta beror på att Angulars standardstrategi för återanvändning av rutter inte kommer att ladda om sidan!

Koden ovan åtgärdar detta standardbeteende men måste placeras i rätt komponent för att få beteendet med omladdning från början.

Observera att det finns alternativ... Anta att du vill behålla hastigheten på komponentåteranvändning. I så fall, ge bara en ingångspunkt till den redan inlästa komponenten som återställer datan, vilket låter komponenten ändras via changeDetectorRef.DetectChanges().

Relaterade artiklar