web-dev-qa-db-fra.com

Angular 4 Le routage ne fonctionne pas sur l'application Web en direct

Mon routage Angular 4 web-app fonctionne correctement dans mon environnement de développement et les redirections de menu fonctionnent correctement dans la version en direct.

Cependant, la version dev redirige vers différentes pages en tapant le champ d'adresse du navigateur, mais pas la version en direct. Est-ce un problème Angular? Ou dois-je gérer mes redirections avec mon FAI?

Mon code app.router.ts est le suivant:

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home/home.component';
import { ArtComponent } from './art/art.component';
import { MusicComponent } from './music/music.component';
import { EventsComponent } from './events/events.component';

export const router: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full'},
{ path: 'home', component: HomeComponent },
{ path: 'art', component: ArtComponent },
{ path: 'music', component: MusicComponent },
{ path: 'events', component: EventsComponent }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

Et dans app.module.ts j'ai:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, } from '@angular/core';
import { RouterModule } from '@angular/router';
import { router } from './app.router';

import 'hammerjs';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import { MdInputModule, MdButtonModule, MdToolbarModule, MdMenuModule, MdGridListModule, MaterialModule, MdDatepickerModule, MdNativeDateModule } from '@angular/material';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { MfToolbarComponent } from './mf-toolbar/mf-toolbar.component';
import { MfMenuComponent } from './mf-menu/mf-menu.component';
import { SplashComponent } from './splash/splash.component';
import { ArtComponent } from './art/art.component';
import { MusicComponent } from './music/music.component';
import { EventsComponent } from './events/events.component';
import { HomeComponent } from './home/home.component';
import { ImageSliderComponent } from './image-slider/image-slider.component';

// import { HTTPTestService } from './date-data.service';
import { AuthenticationService } from './authentication-service.service';

import { DataService } from './data.service';
import { SvgViewerComponent } from './svg-viewer/svg-viewer.component';
import { CalendarComponent } from './calendar/calendar.component';

@NgModule({
  declarations: [
    AppComponent,
    MfToolbarComponent,
    MfMenuComponent,
    SplashComponent,
    ArtComponent,
    MusicComponent,
    EventsComponent,
    HomeComponent,
    ImageSliderComponent,
    SvgViewerComponent,
    CalendarComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    MdInputModule,
    MdButtonModule,
    MdToolbarModule,
    MdMenuModule,
    MdDatepickerModule, 
    MdNativeDateModule,
    HttpModule,
    RouterModule.forRoot( router ),
  ],
  providers: [
    // [HTTPTestService],
    [AuthenticationService],
    [DataService],
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Je ne comprends pas ce que forRoot fait ou s'il convient d'utiliser cela dans Angular 4?

Mon app.component.html est comme suit et utilise une prise de routeur cachée:

<body>
<app-mf-toolbar></app-mf-toolbar>
<router-outlet class="hidden-router"></router-outlet>
</body>

Est-ce que c'est ce comportement de routeur caché que mon application Web en direct ne reproduit pas et comment puis-je changer cela?

J'ai aussi un menu dans menu.component.html qui utilise des liens de routeur et cela fonctionne très bien:

<div class="container">
    <md-menu #appMenu="mdMenu">
        <a routerLink="home">
            <button md-menu-item>
                <md-icon class="material-icons"> home </md-icon>
                <span> Home </span>
            </button>
        </a>
        <a routerLink="art">
            <button md-menu-item>
                <md-icon class="material-icons"> format_Paint </md-icon>
                <span> Art </span>
            </button>
        </a>
        <a routerLink="music">
            <button md-menu-item>
                <md-icon class="material-icons"> music_note </md-icon>
                <span> Music </span>
            </button>
        </a>
        <a routerLink="events">
            <button md-menu-item>
                <md-icon class="material-icons"> event_note </md-icon>
                <span> Events </span>
            </button>
        </a>
    </md-menu>

    <button md-icon-button [mdMenuTriggerFor]="appMenu" color="secondary">
       <i class="material-icons">menu</i>
    </button>
</div>
5
Davtho1983

Le problème que vous avez ici est lié à la nature des cadres d'application à page unique, tels que Angular.

Sur la version déployée de votre application, le serveur Web qui l’héberge ne sait que servir le fichier HTML qu’il voit (index.html), qui correspond à votre chemin racine. La deuxième fois que vous essayez d'accéder directement à http: // url-to-your-app/art , par exemple, le serveur lancera un message 404 non trouvé, car il ne reconnaît pas que le chemin d'une ressource peut être lu. servir.

Lorsque vous naviguez dans votre application à partir de l'application elle-même, c'est le service de routage d'Angular qui gère la navigation côté client. En outre, cela ne se produit pas sur dev, car votre serveur Web sait comment gérer cela. Le serveur Web hôte ne reçoit pas non plus de demandes de publication de pages Web autres que votre index.html.

Vous avez deux options: 

  1. Configurez votre serveur Web de production pour qu'il réponde toujours avec le fichier Index.html chaque fois qu'il détecte un 404 - ainsi, Angular sera toujours chargé et son service de routage se chargera de la navigation côté client.
  2. Changez la stratégie d'emplacement de votre application en stratégie de hachage comme décrit ici . Toutefois, cela modifierait les URL de votre application, et ce n'est pas si souhaitable à mon avis.
16
Andrei Matracaru
RouterModule.forRoot(routes, {useHash: true})

Voir l'utilisation de hashLocationStrategies ici: https://codecraft.tv/courses/angout/routing/routing-strategies/#_hashlocationstrategy

0
vars