~$ git clone https://github.com/Pieter-hogent/recipeapp.git (or git pull) ~$ cd recipeapp ~/recipeapp$ git checkout -b week7 be18b22 ~/recipeapp$ npm install
src/app/add-recipe/add-recipe.component.ts
constructor(
private fb: FormBuilder,
private _recipeDataService: RecipeDataService
) {}
onSubmit() {
// ...
this.newRecipe.emit(new Recipe(this.recipe.value.name, ingredients));
this._recipeDataService
.addNewRecipe(new Recipe(this.recipe.value.name, ingredients));
}
<div fxLayout="column" fxLayoutGap="2%">
<app-add-recipe></app-add-recipe>
<recipe-list></recipe-list>
<div>
8700a3c
src/app/app.module.ts
import { RouterModule, Routes } from '@angular/router';
const appRoutes: Routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent }
];
@NgModule({
imports: [
BrowserModule,
BrowserModule,
RecipeModule,
RouterModule.forRoot(appRoutes)
]
});
src/app/app.component.html
<router-outlet></router-outlet>
const appRoutes: Routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent },
{ path: '', redirectTo: 'recipe/list', pathMatch: 'full'},
{ path: '**', component: PageNotFoundComponent}
];
4d26a16
~$ ng generate @angular/material:material-nav --name=main-nav
src/app/main-nav/main-nav.component.html
<mat-sidenav-container class="sidenav-container">
<mat-sidenav
#drawer
class="sidenav"
fixedInViewport="true"
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
[mode]="(isHandset$ | async) ? 'over' : 'side'"
[opened]="!(isHandset$ | async)"
>
<mat-toolbar>Menu</mat-toolbar>
<mat-nav-list>
<a mat-list-item href="#">Link 1<[routerLink]="['recipe/list']">recipes</a>
<a mat-list-item href="#">Link 2<[routerLink]="['recipe/add']">add recipe</a>
<a mat-list-item href="#">Link 3</a>;
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="primary">
<button [...]>
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<span>recipeapp</span>
</mat-toolbar>
<!-- Add Content Here --><ng-content></ng-content>
</mat-sidenav-content>
</mat-sidenav-container>
src/app/app-component.html
<app-main-nav>
<router-outlet></router-outlet>
</app-main-nav>
a75a6ea
~/recipapp$ ng generate module app-routing --flat --module=app
src/app/app-routing/app-routing.module.ts
import { RouterModule, Routes } from '@angular/router';
import { RecipeListComponent } from './recipe/recipe-list/recipe-list.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const appRoutes: Routes = [ ... ];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
declarations: [],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
41d44e6
~/recipeapp$ ng generate component recipe/RecipeDetail --module=recipe
installing component create src/app/recipe/recipe-detail/recipe-detail.component.css create src/app/recipe/recipe-detail/recipe-detail.component.html create src/app/recipe/recipe-detail/recipe-detail.component.spec.ts create src/app/recipe/recipe-detail/recipe-detail.component.ts update src/app/recipe/recipe.module.ts
src/app/app-routing.module.ts
const routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent },
{ path: 'recipe/detail/:id', component: RecipeDetailComponent},
{ path: '', redirectTo: 'recipe/list', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];
src/app/recipe/recipe-detail/recipe-detail.component.ts
export class RecipeDetailComponent implements OnInit {
public recipe: Recipe;
constructor(private route: ActivatedRoute,
private recipeDataService: RecipeDataService) {
}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.recipeDataService.getRecipe$(id)
.subscribe(item => this.recipe = item);
}
}
f0ea708
src/app/recipe/recipe-detail/recipe-detail.component.ts
export class RecipeDetailComponent implements OnInit {
public recipe: Recipe;
constructor(private route: ActivatedRoute,
private recipeDataService: RecipeDataService) {
}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.recipeDataService.getRecipe$(id)
.subscribe(item => this.recipe = item);
this.route.paramMap.subscribe(pa =>
this.recipeDataService.getRecipe$(pa.get('id'))
.subscribe(item => this.recipe = item)
);
}
}
62f6acf
src/app/recipe/recipe.module.ts
const routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent },
{ path: 'recipe/detail/:id', component: RecipeDetailComponent,
resolve: { recipe: RecipeResolver} }
];
src/app/recipe/RecipeResolver.ts
@Injectable({
providedIn: 'root'
})
export class RecipeResolver implements Resolve<Recipe> {
constructor(private recipeService: RecipeDataService) {}
resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<Recipe> {
return this.recipeService.getRecipe(route.params['id']);
}
}
src/app/recipe/recipe-detail/recipe-detail.component.ts
ngOnInit() {
this.route.data.subscribe(item =>
this.recipe = item['recipe']);
this.route.paramMap.subscribe(pa =>
this.recipeDataService.getRecipe(pa.get('id'))
.subscribe(item => this.recipe = item)
);
}
const routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent },
{ path: 'recipe/detail/:id', component: RecipeDetailComponent,
resolve: { recipe: RecipeResolver }
}
];
@NgModule({
declarations: [
RecipeComponent,
// ...
],
imports: [
CommonModule,
MaterialModule,
HttpClientModule,
ReactiveFormsModule,
RouterModule.forChild(routes)
],
providers: [HttpClientModule]
})
export class RecipeModule {}
src/app/app-routing/app-routing.module.ts
const appRoutes: Routes = [
{ path: '', redirectTo: 'recipe/list', pathMatch: 'full'},
{ path: '**', component: PageNotFoundComponent}
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes, {enableTracing: true})
],
declarations: [],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
src/app/app.module.ts
@NgModule({
declarations: [
AppComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
AppRoutingModule,
RecipeModuleRecipeModule,
AppRoutingModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
337f765
src/app/app-routing/app-routing.module.ts
const appRoutes: Routes = [
{
path: 'recipe',
loadChildren: () => import('./recipe/recipe.module').then(mod => mod.RecipeModule)
},
{ path: '', redirectTo: 'recipe/list', pathMatch: 'full'},
// { path: '', redirectTo: 'recipe/list', pathMatch: 'full'},
{ path: '**', component: PageNotFoundComponent}
];
src/app/recipe/recipe.module.ts
// ...
const routes: Routes = [
{ path: 'recipe/list', component: RecipeListComponent },
{ path: 'recipe/add', component: AddRecipeComponent },
{
path: 'recipe/detail/:id',
component: RecipeDetailComponent,
resolve: { recipe: RecipeResolver }
}
];
// ....
bfd6221
src/app/app-routing.module.ts
@NgModule({
imports: [
RouterModule.forRoot(appRoutes,
{preloadingStrategy: PreloadAllModules})
],
declarations: [],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
src/app/SelectivePreloadStrategy.ts
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class SelectivePreloadStrategy implements PreloadingStrategy {
preload(route: Route, load: Function): Observable<any> {
if (route.data && route.data.preload) {
console.log('preload ' + route.path);
return load();
}
return of(null);
}
}
const appRoutes: Routes = [
{
path: 'recipe',
loadChildren: () => import('./recipe/recipe.module').then(mod => mod.RecipeModule),
data: { preload: true }
}, ... ];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes, {
preloadingStrategy: SelectivePreloadStrategy
})
]
})
export class AppRoutingModule {}
a4591be