Differenzansicht 13-search
im Vergleich zu 12-validation

← Zurück zur Übersicht | Demo | Quelltext auf GitHub
src/app/books-portal/books-overview-page/books-overview-page.html CHANGED
@@ -21,11 +21,12 @@
21
  type="search"
22
  #searchInput
23
  (input)="this.searchTerm.set(searchInput.value)"
 
24
  placeholder="Search"
25
  aria-label="Search"
26
  />
27
 
28
- @for (b of filteredBooks(); track b.isbn) {
29
  <app-book-card [book]="b" (like)="addLikedBook($event)" />
30
  }
31
  </div>
 
21
  type="search"
22
  #searchInput
23
  (input)="this.searchTerm.set(searchInput.value)"
24
+ [value]="this.searchTerm()"
25
  placeholder="Search"
26
  aria-label="Search"
27
  />
28
 
29
+ @for (b of books.value(); track b.isbn) {
30
  <app-book-card [book]="b" (like)="addLikedBook($event)" />
31
  }
32
  </div>
src/app/books-portal/books-overview-page/books-overview-page.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Component, computed, inject, signal } from '@angular/core';
 
2
 
3
  import { Book } from '../../shared/book';
4
  import { BookCard } from '../book-card/book-card';
@@ -12,20 +13,23 @@ import { BookStore } from '../../shared/book-store';
12
  })
13
  export class BooksOverviewPage {
14
  #bookStore = inject(BookStore);
 
15
 
16
- protected searchTerm = signal('');
 
17
 
18
- protected books = this.#bookStore.getAll();
19
  protected likedBooks = signal<Book[]>([]);
20
 
21
- protected filteredBooks = computed(() => {
22
- if (!this.searchTerm()) {
23
- return this.books.value();
24
- }
25
-
26
- const term = this.searchTerm().toLowerCase();
27
- return this.books.value().filter((b) => b.title.toLowerCase().includes(term));
28
- });
 
29
 
30
  addLikedBook(newLikedBook: Book) {
31
  const foundBook = this.likedBooks().find(
 
1
+ import { Component, effect, inject, input, linkedSignal, signal } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
 
4
  import { Book } from '../../shared/book';
5
  import { BookCard } from '../book-card/book-card';
 
13
  })
14
  export class BooksOverviewPage {
15
  #bookStore = inject(BookStore);
16
+ #router = inject(Router);
17
 
18
+ readonly search = input<string>();
19
+ protected searchTerm = linkedSignal(() => this.search() || '');
20
 
21
+ protected books = this.#bookStore.getAll(this.searchTerm);
22
  protected likedBooks = signal<Book[]>([]);
23
 
24
+ constructor() {
25
+ effect(() => {
26
+ this.#router.navigate([], {
27
+ queryParams: {
28
+ search: this.searchTerm() || null
29
+ }
30
+ });
31
+ });
32
+ }
33
 
34
  addLikedBook(newLikedBook: Book) {
35
  const foundBook = this.likedBooks().find(
src/app/shared/book-store.ts CHANGED
@@ -11,9 +11,12 @@ export class BookStore {
11
  #http = inject(HttpClient);
12
  #apiUrl = 'https://api6.angular-buch.com';
13
 
14
- getAll(): HttpResourceRef<Book[]> {
15
  return httpResource<Book[]>(
16
- () => `${this.#apiUrl}/books`,
 
 
 
17
  { defaultValue: [] }
18
  );
19
  }
 
11
  #http = inject(HttpClient);
12
  #apiUrl = 'https://api6.angular-buch.com';
13
 
14
+ getAll(searchTerm: Signal<string>): HttpResourceRef<Book[]> {
15
  return httpResource<Book[]>(
16
+ () => ({
17
+ url: `${this.#apiUrl}/books`,
18
+ params: { search: searchTerm() }
19
+ }),
20
  { defaultValue: [] }
21
  );
22
  }