Angular 6-动态子路线

时间:2018-07-29 20:10:22

标签: angular angular-router

我正在学习Angular 6,却被卡在路由器上。 ⛔️

app-routing.module.ts

import { NgModule } from '@angular/core';
import { WeatherComponent } from './weather/weather.component';
import { ForecastComponent } from './forecast/forecast.component';
import { ForecastDailyComponent } from './forecast-daily/forecast-daily.component';
import { ForecastResolverService } from './shared/services/resolvers/forecast-resolver.service';
import { ForecastDailyResolverService } from './shared/services/resolvers/forecast-daily-resolver.service';

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

export const routes: Routes = [
  {
    path: '',
    component: WeatherComponent,
    pathMatch: 'full',
  },
  {
    path: ':name',
    component: ForecastComponent,
    resolve: {
      forecast: ForecastResolverService,
    },
    children: [
      {
        path: ':day',
        // i had here pathMatch: 'full', does not help
        component: ForecastDailyComponent,
        resolve: {
          forecast: ForecastDailyResolverService
        }
      }
    ]
  },
  {
    path: '**',
    redirectTo: '',
    pathMatch: 'full'
  }
];
const ENABLE_TRACING = true;

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      enableTracing: ENABLE_TRACING,
      preloadingStrategy: PreloadAllModules,
    }),
  ],
  exports: [
    RouterModule
  ],
})
export class AppRoutingModule {}

forecast-resolver.sevice.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Resolve } from '@angular/router';

import { WeatherForecastPayload } from '../../../shared/models/weather-forecast-payload.model';
import { WeatherService } from '../../../shared/services/weather.service';
import { CityService } from '../../../shared/services/city.service';
import { Observable } from 'rxjs';

@Injectable()
export class ForecastResolverService implements Resolve<WeatherForecastPayload> {

  constructor(
    private weatherService: WeatherService,
    private cityService: CityService,

  ) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<WeatherForecastPayload> {
    const name = route.paramMap.get('name');
    const forecast = this.weatherService.getForecast(this.cityService.getCityID(name));
    return forecast;
  }
}

forecast-daily-resolver.sevice.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Resolve } from '@angular/router';

import { WeatherForecast } from '../../models/weather-forecast.model';
import { StoreService } from '../../services/store.service';
import { WeatherForecastPayload } from '../../models/weather-forecast-payload.model';
import { getWeekDayNumber } from '../../utils/converters';

@Injectable()
export class ForecastDailyResolverService implements Resolve<Array<WeatherForecast>> {

  constructor(
    private store: StoreService,
  ) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const day = route.paramMap.get('day');

    const forecast: WeatherForecastPayload = this.store.get('forecast');

    const dailyForecast = forecast.list.filter(
      (item) => {
        const forecastDay = getWeekDayNumber(String(new Date(item.dt_txt).getDay()));
        if (day === forecastDay) {
          return item;
        }
      }
    );
    return dailyForecast;
  }
}

weather.component.ts ,带有指向/:name路线的链接

<div class="jumbotron-fluid h-100 text-center m-0 d-flex flex-column justify-content-center">
  <div class="container-fluid h-100">
    <div class="row h-100">
      <div *ngFor="let weather of weatherList" class="col-lg m-4">
        <!-- weather.name ends up being London,Berlin or other city -->
        <app-weather-card [routerLink]="[weather.name]" [weather]="weather">
        </app-weather-card>
      </div>
    </div>
  </div>
</div>

forecast.component.ts ,带有指向/:name /:day路线的链接

<div class="jumbotron-fluid h-100 text-center m-0 d-flex flex-column justify-content-center">
  <div class="container-fluid h-100">
    <div class="row h-100">
      <div *ngFor="let dailyForecastList of forecastList" class="col-lg m-4">
        <app-forecast-card
          <!-- getDay() returns Mon or Thu or Fri etc. -->
          [routerLink]="[getDay(dailyForecastList.dt_txt)]"
          [forecast]="dailyForecastList">
        </app-forecast-card>
      </div>
    </div>
  </div>
</div>
<router-outlet></router-outlet>

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { SharedModule } from './shared';
import { WeatherModule } from './weather/weather.module';
import { ForecastModule } from './forecast/forecast.module';
import { ForecastDailyModule } from './forecast-daily/forecast-daily.module';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    SharedModule,
    BrowserModule,
    WeatherModule,
    ForecastModule,
    ForecastDailyModule,
    AppRoutingModule,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

shared.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';


import { WeatherIconComponent } from './components/weather/weather-icon/weather-icon.component';
import { WeatherTemperatureComponent } from './components/weather/weather-temperature/weather-temperature.component';
import { WeatherCardComponent } from './components/weather/weather-card/weather-card.component';
import { ForecastCardComponent } from './components/weather/forecast-card/forecast-card.component';
import { NavigationComponent } from './components/navigation/navigation.component';
import { FooterComponent } from './components/footer/footer.component';

import { StoreService } from '../shared/services/store.service';


@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    RouterModule,
    ReactiveFormsModule,
    HttpClientModule,
  ],
  exports: [
    CommonModule,
    FormsModule,
    RouterModule,
    ReactiveFormsModule,
    HttpClientModule,
    WeatherIconComponent,
    WeatherTemperatureComponent,
    WeatherCardComponent,
    ForecastCardComponent,
    NavigationComponent,
    FooterComponent,
  ],
  declarations: [
    WeatherIconComponent,
    WeatherTemperatureComponent,
    WeatherCardComponent,
    ForecastCardComponent,
    NavigationComponent,
    FooterComponent,
  ],
  providers: [StoreService],
})
export class SharedModule {}

store.service.ts 用于保存全局数据的简单存储

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class StoreService {

  constructor() { }

  protected store$: Map<string, any> = new Map();
  public subject = new BehaviorSubject(this.store$);

  public get(key: any): any {
    return this.store$.get(key);
  }

  public set(key: any, value: any) {
    this.store$.set(key, value);
  }

}

在进入路线“”(其中包含天气组件)中,您会看到5个位置的“天气”列表,当单击其中一个路由器时,会将我们带到/:name并行路线,在那里您可以看到对下5个位置的预报以行的形式显示天,单击其中的一个将导致我们找到该天/:name /:day的每小时预测列表,但是我可以在其中看到':name'的内容,并且我希望仅看到每小时的预测列表

如果需要,我可以添加更多文件,但是我认为我发布的最相关。

谢谢。

2 个答案:

答案 0 :(得分:2)

经过多次尝试和100个可见的示例(这些示例都没有朝这个方向发展)之后,我决定尝试使用此路由器配置,并且可以正常工作,希望对某些人有所帮助。

app-routing.module.ts

import { NgModule } from '@angular/core';

import { WeatherComponent } from './weather/weather.component';
import { ForecastComponent } from './forecast/forecast.component';
import { ForecastDailyComponent } from './forecast-daily/forecast-daily.component';
import { ForecastResolverService } from './shared/services/resolvers/forecast-resolver.service';
import { ForecastDailyResolverService } from './shared/services/resolvers/forecast-daily-resolver.service';

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

export const routes: Routes = [
  {
    path: '',
    component: WeatherComponent,
  },
  {
    path: ':name',
    component: ForecastComponent,
    resolve: {
      forecast: ForecastResolverService,
    }
  },
  {
    path: ':name/:day',
    component: ForecastDailyComponent,
    resolve: {
      forecast: ForecastDailyResolverService
    }
  },
  {
    path: '**',
    redirectTo: '',
    pathMatch: 'full'
  }
];

const ENABLE_TRACING = false;

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      enableTracing: ENABLE_TRACING,
      preloadingStrategy: PreloadAllModules,
    }),
  ],
  exports: [
    RouterModule
  ],
})
export class AppRoutingModule {}

答案 1 :(得分:0)

由于ForecastComponent具有子路线,因此请确保该组件在其自己的模板中具有<router-outlet>,Angular可以在其中放置子路线