Differenzansicht 06-routing
im Vergleich zu 05-di

← Zurück zur Übersicht | Demo | Quelltext auf GitHub
src/app/app-routing.module.ts CHANGED
@@ -1,7 +1,19 @@
1
  import { NgModule } from '@angular/core';
2
  import { RouterModule, Routes } from '@angular/router';
3
 
4
- const routes: Routes = [];
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  @NgModule({
7
  imports: [RouterModule.forRoot(routes)],
1
  import { NgModule } from '@angular/core';
2
  import { RouterModule, Routes } from '@angular/router';
3
 
4
+ import { HomeComponent } from './home/home.component';
5
+
6
+ const routes: Routes = [
7
+ {
8
+ path: '',
9
+ redirectTo: 'home',
10
+ pathMatch: 'full'
11
+ },
12
+ {
13
+ path: 'home',
14
+ component: HomeComponent,
15
+ },
16
+ ];
17
 
18
  @NgModule({
19
  imports: [RouterModule.forRoot(routes)],
src/app/app.component.html CHANGED
@@ -1,6 +1,8 @@
 
 
 
 
 
1
  <main>
2
- <bm-book-list *ngIf="!book"
3
- (selectBook)="showDetails($event)"></bm-book-list>
4
- <bm-book-details *ngIf="book"
5
- (leave)="showList()" [book]="book"></bm-book-details>
6
  </main>
1
+ <nav>
2
+ <a routerLink="/home" routerLinkActive="active" ariaCurrentWhenActive="page">Home</a>
3
+ <a routerLink="/books" routerLinkActive="active" ariaCurrentWhenActive="page">Books</a>
4
+ </nav>
5
+
6
  <main>
7
+ <router-outlet></router-outlet>
 
 
 
8
  </main>
src/app/app.component.ts CHANGED
@@ -1,19 +1,8 @@
1
  import { Component } from '@angular/core';
2
- import { Book } from './shared/book';
3
 
4
  @Component({
5
  selector: 'bm-root',
6
  templateUrl: './app.component.html',
7
  styleUrls: ['./app.component.css']
8
  })
9
- export class AppComponent {
10
- book: Book | null = null;
11
-
12
- showList() {
13
- this.book = null;
14
- }
15
-
16
- showDetails(book: Book) {
17
- this.book = book;
18
- }
19
- }
1
  import { Component } from '@angular/core';
 
2
 
3
  @Component({
4
  selector: 'bm-root',
5
  templateUrl: './app.component.html',
6
  styleUrls: ['./app.component.css']
7
  })
8
+ export class AppComponent {}
 
 
 
 
 
 
 
 
 
 
src/app/app.module.ts CHANGED
@@ -4,10 +4,12 @@ import { BrowserModule } from '@angular/platform-browser';
4
  import { AppRoutingModule } from './app-routing.module';
5
  import { AppComponent } from './app.component';
6
  import { BooksModule } from './books/books.module';
 
7
 
8
  @NgModule({
9
  declarations: [
10
  AppComponent,
 
11
  ],
12
  imports: [
13
  BrowserModule,
4
  import { AppRoutingModule } from './app-routing.module';
5
  import { AppComponent } from './app.component';
6
  import { BooksModule } from './books/books.module';
7
+ import { HomeComponent } from './home/home.component';
8
 
9
  @NgModule({
10
  declarations: [
11
  AppComponent,
12
+ HomeComponent,
13
  ],
14
  imports: [
15
  BrowserModule,
src/app/books/book-details/book-details.component.html CHANGED
@@ -22,7 +22,5 @@
22
  <img *ngIf="book.thumbnailUrl"
23
  [src]="book.thumbnailUrl"
24
  alt="Cover">
25
- <button class="arrow-left" (click)="doLeave()">
26
- Back to list
27
- </button>
28
  </div>
22
  <img *ngIf="book.thumbnailUrl"
23
  [src]="book.thumbnailUrl"
24
  alt="Cover">
25
+ <a class="button arrow-left" routerLink="..">Back to list</a>
 
 
26
  </div>
src/app/books/book-details/book-details.component.ts CHANGED
@@ -1,4 +1,7 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
 
 
 
2
  import { Book } from '../../shared/book';
3
 
4
  @Component({
@@ -7,10 +10,12 @@ import { Book } from '../../shared/book';
7
  styleUrls: ['./book-details.component.css']
8
  })
9
  export class BookDetailsComponent {
10
- @Input() book?: Book;
11
- @Output() leave = new EventEmitter<void>();
12
-
13
- doLeave() {
14
- this.leave.emit();
 
 
15
  }
16
  }
1
+ import { Component } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+
4
+ import { BookStoreService } from '../../shared/book-store.service';
5
  import { Book } from '../../shared/book';
6
 
7
  @Component({
10
  styleUrls: ['./book-details.component.css']
11
  })
12
  export class BookDetailsComponent {
13
+ book?: Book;
14
+ constructor(
15
+ private service: BookStoreService,
16
+ private route: ActivatedRoute,
17
+ ) {
18
+ const isbn = this.route.snapshot.paramMap.get('isbn')!;
19
+ this.book = this.service.getSingle(isbn);
20
  }
21
  }
src/app/books/book-list/book-list.component.html CHANGED
@@ -1,7 +1,7 @@
1
  <h1>Books</h1>
2
  <ul class="book-list">
3
  <li *ngFor="let book of books">
4
- <bm-book-list-item [book]="book" (click)="doSelect(book)"></bm-book-list-item>
5
  </li>
6
  <li *ngIf="!books.length">
7
  No books available.
1
  <h1>Books</h1>
2
  <ul class="book-list">
3
  <li *ngFor="let book of books">
4
+ <bm-book-list-item [book]="book"></bm-book-list-item>
5
  </li>
6
  <li *ngIf="!books.length">
7
  No books available.
src/app/books/book-list/book-list.component.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Component, EventEmitter, Output } from '@angular/core';
2
 
3
  import { BookStoreService } from '../../shared/book-store.service';
4
  import { Book } from '../../shared/book';
@@ -10,13 +10,8 @@ import { Book } from '../../shared/book';
10
  })
11
  export class BookListComponent {
12
  books: Book[] = [];
13
- @Output() selectBook = new EventEmitter<Book>();
14
 
15
  constructor(private service: BookStoreService) {
16
  this.books = this.service.getAll();
17
  }
18
-
19
- doSelect(book: Book) {
20
- this.selectBook.emit(book);
21
- }
22
  }
1
+ import { Component } from '@angular/core';
2
 
3
  import { BookStoreService } from '../../shared/book-store.service';
4
  import { Book } from '../../shared/book';
10
  })
11
  export class BookListComponent {
12
  books: Book[] = [];
 
13
 
14
  constructor(private service: BookStoreService) {
15
  this.books = this.service.getAll();
16
  }
 
 
 
 
17
  }
src/app/books/book-list-item/book-list-item.component.html CHANGED
@@ -1,4 +1,4 @@
1
- <div *ngIf="book" class="list-item">
2
  <img *ngIf="book.thumbnailUrl" [src]="book.thumbnailUrl" alt="Cover">
3
  <h2>{{ book.title }}</h2>
4
  <p role="doc-subtitle" *ngIf="book.subtitle">
@@ -10,4 +10,4 @@
10
  </li>
11
  </ul>
12
  <div>ISBN {{ book.isbn }}</div>
13
- </div>
1
+ <a *ngIf="book" [routerLink]="book.isbn" class="list-item">
2
  <img *ngIf="book.thumbnailUrl" [src]="book.thumbnailUrl" alt="Cover">
3
  <h2>{{ book.title }}</h2>
4
  <p role="doc-subtitle" *ngIf="book.subtitle">
10
  </li>
11
  </ul>
12
  <div>ISBN {{ book.isbn }}</div>
13
+ </a>
src/app/books/book-list-item/book-list-item.component.spec.ts CHANGED
@@ -1,23 +1,42 @@
 
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
 
2
 
3
  import { BookListItemComponent } from './book-list-item.component';
4
 
5
  describe('BookListItemComponent', () => {
6
  let component: BookListItemComponent;
7
  let fixture: ComponentFixture<BookListItemComponent>;
 
8
 
9
  beforeEach(async () => {
10
  await TestBed.configureTestingModule({
11
- declarations: [ BookListItemComponent ]
 
 
 
 
 
12
  })
13
  .compileComponents();
14
 
 
15
  fixture = TestBed.createComponent(BookListItemComponent);
16
  component = fixture.componentInstance;
 
 
 
 
 
 
 
17
  fixture.detectChanges();
18
  });
19
 
20
- it('should create', () => {
21
- expect(component).toBeTruthy();
 
 
 
22
  });
23
  });
1
+ import { Location } from '@angular/common';
2
  import { ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { RouterTestingModule } from '@angular/router/testing';
4
 
5
  import { BookListItemComponent } from './book-list-item.component';
6
 
7
  describe('BookListItemComponent', () => {
8
  let component: BookListItemComponent;
9
  let fixture: ComponentFixture<BookListItemComponent>;
10
+ let location: Location;
11
 
12
  beforeEach(async () => {
13
  await TestBed.configureTestingModule({
14
+ declarations: [BookListItemComponent],
15
+ imports: [
16
+ RouterTestingModule.withRoutes([
17
+ { path: ':isbn', children: [] }
18
+ ])
19
+ ]
20
  })
21
  .compileComponents();
22
 
23
+ location = TestBed.inject(Location);
24
  fixture = TestBed.createComponent(BookListItemComponent);
25
  component = fixture.componentInstance;
26
+ // Buch zum Anzeigen
27
+ component.book = {
28
+ isbn: '111',
29
+ title: 'Book 1',
30
+ authors: [],
31
+ thumbnailUrl: 'https://cdn.ng-buch.de/kochen.png'
32
+ };
33
  fixture.detectChanges();
34
  });
35
 
36
+ it('should navigate to details page by ISBN', async () => {
37
+
38
+ fixture.nativeElement.querySelector('img').click();
39
+ await fixture.whenStable();
40
+ expect(location.path()).toEqual('/111');
41
  });
42
  });
src/app/books/books-routing.module.ts CHANGED
@@ -1,7 +1,19 @@
1
  import { NgModule } from '@angular/core';
2
  import { RouterModule, Routes } from '@angular/router';
3
 
4
- const routes: Routes = [];
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  @NgModule({
7
  imports: [RouterModule.forChild(routes)],
1
  import { NgModule } from '@angular/core';
2
  import { RouterModule, Routes } from '@angular/router';
3
 
4
+ import { BookDetailsComponent } from './book-details/book-details.component';
5
+ import { BookListComponent } from './book-list/book-list.component';
6
+
7
+ const routes: Routes = [
8
+ {
9
+ path: 'books',
10
+ component: BookListComponent,
11
+ },
12
+ {
13
+ path: 'books/:isbn',
14
+ component: BookDetailsComponent,
15
+ }
16
+ ];
17
 
18
  @NgModule({
19
  imports: [RouterModule.forChild(routes)],
src/app/books/books.module.ts CHANGED
@@ -15,10 +15,6 @@ import { BookDetailsComponent } from './book-details/book-details.component';
15
  imports: [
16
  CommonModule,
17
  BooksRoutingModule
18
- ],
19
- exports: [
20
- BookListComponent,
21
- BookDetailsComponent
22
  ]
23
  })
24
  export class BooksModule { }
15
  imports: [
16
  CommonModule,
17
  BooksRoutingModule
 
 
 
 
18
  ]
19
  })
20
  export class BooksModule { }
src/app/home/home.component.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <h1>Home</h1>
2
+
3
+ <a routerLink="/books" class="button red">
4
+ Show book list
5
+ </a>
src/app/{books/book-details/book-details.component.spec.ts → home/home.component.spec.ts} RENAMED
@@ -1,18 +1,18 @@
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
 
3
- import { BookDetailsComponent } from './book-details.component';
4
 
5
- describe('BookDetailsComponent', () => {
6
- let component: BookDetailsComponent;
7
- let fixture: ComponentFixture<BookDetailsComponent>;
8
 
9
  beforeEach(async () => {
10
  await TestBed.configureTestingModule({
11
- declarations: [ BookDetailsComponent ]
12
  })
13
  .compileComponents();
14
 
15
- fixture = TestBed.createComponent(BookDetailsComponent);
16
  component = fixture.componentInstance;
17
  fixture.detectChanges();
18
  });
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
 
3
+ import { HomeComponent } from './home.component';
4
 
5
+ describe('HomeComponent', () => {
6
+ let component: HomeComponent;
7
+ let fixture: ComponentFixture<HomeComponent>;
8
 
9
  beforeEach(async () => {
10
  await TestBed.configureTestingModule({
11
+ declarations: [ HomeComponent ]
12
  })
13
  .compileComponents();
14
 
15
+ fixture = TestBed.createComponent(HomeComponent);
16
  component = fixture.componentInstance;
17
  fixture.detectChanges();
18
  });
src/app/home/home.component.ts ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'bm-home',
5
+ templateUrl: './home.component.html',
6
+ styleUrls: ['./home.component.css']
7
+ })
8
+ export class HomeComponent {}
src/app/shared/book-store.service.spec.ts CHANGED
@@ -1,15 +1,16 @@
 
 
1
  import { BookStoreService } from './book-store.service';
2
 
3
  describe('BookStoreService', () => {
4
-
5
  let service: BookStoreService;
6
 
7
  beforeEach(() => {
8
- service = new BookStoreService();
 
9
  });
10
 
11
- it('should hold a hardcoded list of 2 books', () => {
12
- const books = service.getAll();
13
- expect(books).toHaveSize(2);
14
  });
15
  });
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
  import { BookStoreService } from './book-store.service';
4
 
5
  describe('BookStoreService', () => {
 
6
  let service: BookStoreService;
7
 
8
  beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(BookStoreService);
11
  });
12
 
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
 
15
  });
16
  });
src/app/shared/book-store.service.ts CHANGED
@@ -34,4 +34,8 @@ export class BookStoreService {
34
  getAll(): Book[] {
35
  return this.books;
36
  }
 
 
 
 
37
  }
34
  getAll(): Book[] {
35
  return this.books;
36
  }
37
+
38
+ getSingle(isbn: string): Book | undefined {
39
+ return this.books.find(book => book.isbn === isbn);
40
+ }
41
  }