我将angular.io的angular 2英雄教程作为一个简单的联系人列表教育项目的模板。 到目前为止,一切都很好,除了搜索不起作用。我已经逐步尝试了模板...首先我使用了代码文件数据集,但是当应用http和rest api时,搜索以某种方式破坏了。在浏览器中,我能够从手写的url请求中获取json结果,但是角度代码有一个未知的问题。 这是代码:
应用/ contato搜索/ contato-search.component.html
<div id="search-component">
<h4>Busca Contato</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<ul class="search-result">
<li *ngFor="let contato of contatos$ | async" >
<a routerLink="/detalhe/{{contato.id}}">
{{contato.nome}}
</a>
</li>
</ul>
</div>
应用/ contato搜索/ contato-search.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { of } from 'rxjs/observable/of';
import {
debounceTime, distinctUntilChanged, switchMap
} from 'rxjs/operators';
import { Contato } from '../contato';
import { ContatoService } from '../contato.service';
@Component({
selector: 'app-contato-search',
templateUrl: './contato-search.component.html',
styleUrls: ['./contato-search.component.css']
})
export class ContatoSearchComponent implements OnInit {
contatos$: Observable<Contato[]>;
private searchTerms = new Subject<string>();
constructor(private contatoService: ContatoService) {}
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
this.contatos$ = 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.contatoService.searchContatos(term)),
);
}
}
应用/应用-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ContatosComponent } from './contatos/contatos.component';
import { ContatoDetalheComponent } from './contato-detalhe/contato-detalhe.component';
import { ContatoAddComponent } from './contato-add/contato-add.component';
import { ContatoSearchComponent } from './contato-search/contato-search.component';
const routes: Routes = [
{ path: '', redirectTo: '/', pathMatch: 'full' },
{ path: 'detalhe/:id', component: ContatoDetalheComponent },
{ path: 'contatos', component: ContatosComponent },
{ path: 'contato-search', component: ContatoSearchComponent},
{ path: 'contato-add', component: ContatoAddComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule { }
应用/ contato.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Contato } from './contato';
import { MessageService } from './message.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
import { Message } from '_debugger';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class ContatoService {
constructor(
private http: HttpClient,
private messageService: MessageService) { }
private contatosUrl = 'http://localhost/contatos_api/contato'; // URL to web api
getContatos(): Observable<Contato[]> {
// Todo: send the message _after_ fetching the contatos
//this.messageService.add('ContatoService: fetched contatos');
return this.http.get<Contato[]>(`${this.contatosUrl}/read.php`)
.pipe(
tap(contatos => this.log(`fetched contatos`)),
catchError(this.handleError('getContatos', []))
);
}
getContato(id: number): Observable<Contato> {
// Todo: send the message _after_ fetching the contato
const url = `${this.contatosUrl}/read_one.php?id=${id}`;
this.messageService.add(`ContatoService: fetched contato id=${id}`);
return this.http.get<Contato>(url).pipe(
tap(_ => this.log(`fetched contato id=${id}`)),
catchError(this.handleError<Contato>(`getContato id=${id}`))
);
}
/** PUT:on the server */
updateContato (contato: Contato): Observable<Contato> {
return this.http.put(this.contatosUrl+"/update.php", contato, httpOptions).pipe(
tap(_ => this.log(`updated contato id=${contato.id}`)),
catchError(this.handleError<any>('updateContato'))
);
}
/** POST: add a new to the server */
addContato (contato: Contato): Observable<Contato> {
return this.http.post<Contato>(this.contatosUrl+"/create.php", contato, httpOptions).pipe(
tap((contato: Contato) => this.log(`added contato w/ id=${contato.id}`)),
catchError(this.handleError<Contato>('addContato'))
);
}
/** DELETE: delete the from the server */
deleteContato (contato: Contato | number): Observable<Contato> {
let url:string;
if (typeof contato === 'number'){
url = `${this.contatosUrl}/delete.php?id=${contato}`;
return this.http.delete<Contato>(url, httpOptions).pipe(
tap(_ => this.log(`deleted contato id=${contato}`)),
catchError(this.handleError<Contato>('deleteContato'))
);
}else{
url = `${this.contatosUrl}/delete.php?id=${contato.id}`;
return this.http.delete<Contato>(url, httpOptions).pipe(
tap(_ => this.log(`deleted contato id=${contato.id}`)),
catchError(this.handleError<Contato>('deleteContato'))
);
}
}
/* GET contatos whose name contains search term */
searchContatos(term: string): Observable<Contato[]> {
return this.http.get<Contato[]>(`${this.contatosUrl}/search.php?s=${term}`).pipe(
tap(_ => this.log(`found contatos matching "${term}"`)),
catchError(this.handleError<Contato[]>('searchContatos', []))
);
}
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
this.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
/** Log a ContatoService message with the MessageService */
private log(m: string) {
this.messageService.add('ContatoService: ' + m);
}
}
我相信关键文件在那里。有谁知道如何让搜索工作正常?提前谢谢。