使用angular 2和php rest api进行异步搜索

时间:2018-01-05 20:51:59

标签: angular typescript

我将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);
    }
}

我相信关键文件在那里。有谁知道如何让搜索工作正常?提前谢谢。

0 个答案:

没有答案