Differenzansicht 15-rxjs
im Vergleich zu 14-lazyloading

Zurück zur Übersicht | ← Vorherige | Demo | Quelltext auf GitHub
src/app/home-page/home-page.html CHANGED
@@ -1 +1,15 @@
1
  <h1>Welcome to the BookManager!</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h1>Welcome to the BookManager!</h1>
2
+
3
+ <section [attr.aria-busy]="isLoading()">
4
+ <label for="search">Search for Books</label>
5
+ <input type="search" id="search" [field]="searchField" />
6
+ <ul>
7
+ @for (b of results(); track b.isbn) {
8
+ <li>
9
+ <a [routerLink]="['/books', 'details', b.isbn]">
10
+ {{ b.title }} / {{ b.isbn }}
11
+ </a>
12
+ </li>
13
+ }
14
+ </ul>
15
+ </section>
src/app/home-page/home-page.ts CHANGED
@@ -1,11 +1,33 @@
1
- import { Component } from '@angular/core';
 
 
 
 
 
 
2
 
3
  @Component({
4
  selector: 'app-home-page',
5
- imports: [],
6
  templateUrl: './home-page.html',
7
  styleUrl: './home-page.scss'
8
  })
9
  export class HomePage {
 
 
 
 
 
10
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
 
1
+ import { Component, inject, signal } from '@angular/core';
2
+ import { RouterLink } from '@angular/router';
3
+ import { Field, form } from '@angular/forms/signals';
4
+ import { toObservable, toSignal } from '@angular/core/rxjs-interop';
5
+ import { filter, debounceTime, distinctUntilChanged, switchMap, tap } from 'rxjs';
6
+
7
+ import { BookStore } from '../shared/book-store';
8
 
9
  @Component({
10
  selector: 'app-home-page',
11
+ imports: [Field, RouterLink],
12
  templateUrl: './home-page.html',
13
  styleUrl: './home-page.scss'
14
  })
15
  export class HomePage {
16
+ #bookStore = inject(BookStore);
17
+
18
+ protected searchTerm = signal('');
19
+ protected searchField = form(this.searchTerm);
20
+ protected isLoading = signal(false);
21
 
22
+ protected results = toSignal(
23
+ toObservable(this.searchTerm).pipe(
24
+ filter(term => term.length >= 3),
25
+ debounceTime(500),
26
+ distinctUntilChanged(),
27
+ tap(() => this.isLoading.set(true)),
28
+ switchMap(term => this.#bookStore.search(term)),
29
+ tap(() => this.isLoading.set(false)),
30
+ ),
31
+ { initialValue: [] }
32
+ );
33
  }
src/app/shared/book-store.ts CHANGED
@@ -34,4 +34,11 @@ export class BookStore {
34
  create(book: Book): Observable<Book> {
35
  return this.#http.post<Book>(`${this.#apiUrl}/books`, book);
36
  }
 
 
 
 
 
 
 
37
  }
 
34
  create(book: Book): Observable<Book> {
35
  return this.#http.post<Book>(`${this.#apiUrl}/books`, book);
36
  }
37
+
38
+ search(searchTerm: string): Observable<Book[]> {
39
+ return this.#http.get<Book[]>(
40
+ `${this.#apiUrl}/books`,
41
+ { params: { search: searchTerm } }
42
+ );
43
+ }
44
  }