Compare commits

...

9 Commits

7 changed files with 125 additions and 2 deletions

View File

@ -7,7 +7,7 @@ export const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' }, //путь по умолчанию
{ path: 'heroes', component: HeroesComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
];

View File

@ -5,3 +5,5 @@
{{hero.name}}
</a>
</div>
<app-hero-search></app-hero-search>

View File

@ -3,10 +3,11 @@ import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { RouterLink } from '@angular/router';
import { HeroSearchComponent } from "../hero-search/hero-search.component";
@Component({
selector: 'app-dashboard.component',
imports: [CommonModule, RouterLink],
imports: [CommonModule, RouterLink, HeroSearchComponent],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.css'
})

View File

@ -0,0 +1,47 @@
/* HeroSearch private styles */
label {
display: block;
font-weight: bold;
font-size: 1.2rem;
margin-top: 1rem;
margin-bottom: .5rem;
}
input {
padding: .5rem;
width: 100%;
max-width: 600px;
box-sizing: border-box;
display: block;
}
input:focus {
outline: #336699 auto 1px;
}
li {
list-style-type: none;
}
.search-result li a {
border-bottom: 1px solid gray;
border-left: 1px solid gray;
border-right: 1px solid gray;
display: inline-block;
width: 100%;
max-width: 600px;
padding: .5rem;
box-sizing: border-box;
text-decoration: none;
color: black;
}
.search-result li a:hover {
background-color: #435A60;
color: white;
}
ul.search-result {
margin-top: 0;
padding-left: 0;
}

View File

@ -0,0 +1,14 @@
<div id="search-component">
<label for="search-box">Hero Search</label>
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<ul class="search-result">
<li *ngFor="let hero of heroes$ | async" >
<a routerLink="/detail/{{hero.id}}">
{{hero.name}}
</a>
</li>
</ul>
</div>
<!--a> тест ветки </a-->

View File

@ -0,0 +1,44 @@
//test fork
import { Component, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import {
debounceTime, distinctUntilChanged, switchMap
} from 'rxjs/operators';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { CommonModule } from '@angular/common'; //добавил библиотеку
import { RouterLink } from '@angular/router'; //добавил библиотеку
@Component({
selector: 'app-hero-search',
imports: [CommonModule, RouterLink],
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ]
})
export class HeroSearchComponent implements OnInit {
heroes$!: Observable<Hero[]>;
private searchTerms = new Subject<string>();
constructor(private heroService: HeroService) {}
ngOnInit(): void {
this.heroes$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// switch to new search observable each time the term changes
switchMap((term: string) => this.heroService.searchHeroes(term)),
);
}
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
}

View File

@ -65,6 +65,21 @@ export class HeroService {
catchError(this.handleError<Hero>('deleteHero'))
);
}
/* GET heroes whose name contains search term */
searchHeroes(term: string): Observable<Hero[]> {
if (!term.trim()) {
// if not search term, return empty hero array.
return of([]);
}
return this.http.get<Hero[]>(`${this.heroesUrl}/?name=${term}`)
.pipe(
tap(x => x.length ?
this.log(`found heroes matching "${term}"`) :
this.log(`no heroes matching "${term}"`)),
catchError(this.handleError<Hero[]>('searchHeroes', []))
);
}
/**
* Handle Http operation that failed.