《angular2获取数据用列表显示》中我们做了简单的获取数据,并将获取的数据显示在html列表中,这次我们做的是,在文本框中输入关键词,获取服务器数据并显示符合要求的数据。
做这个小例子前,我们需要新建一个项目:
1 2 3 4 |
git clone https://github.com/angular/quickstart.git quickstart cd quickstart npm install npm start |
下一步,在app/app.module.ts中导入RxJS Observable
扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Observable class extensions import 'rxjs/add/observable/of'; import 'rxjs/add/observable/throw'; // Observable operators import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/switchMap'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule,HttpModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } |
下面来看看实现代码(app/app.component.ts):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import {Component, OnInit} from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable } from 'rxjs'; import { Subject } from 'rxjs/Subject'; import 'rxjs/Rx'; // Observable class extensions import 'rxjs/add/observable/of'; import 'rxjs/add/observable/throw'; // Observable operators import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/switchMap'; @Component({ selector: 'my-app', template: ` <h1>Hello {{name}}</h1> <input #searchBox id="search-box" (keyup)="search(searchBox.value)" /> <ul *ngIf="heroes$"> <li *ngFor="let heroe of heroes$ | async "> <span>{{heroe.id}}</span> {{heroe.name}} </li> </ul> `, }) export class AppComponent implements OnInit{ heroes$: Observable<any[]>; private searchTerms = new Subject(); name = 'Angular'; constructor(public http: Http) { } ngOnInit(): void { this.heroes$=this.searchTerms .debounceTime(300) // wait for 300ms pause in events .distinctUntilChanged() // ignore if next search term is same as previous .switchMap(term => { return this.http.get('http://localhost/angluarjson.php?name='+term).map((r: Response) => r.json()); }); } search(term: string): void { this.searchTerms.next(term); } } |
这一次我们更加深入的使用了RXJS
首先我们新建一个new Subject,Subject维护着自己的Observer,什么是Subject? 在RxJS中,Subject是一类特殊的Observable,它可以向多个Observer多路推送数值。普通的Observable并不具备多路推送的能力(每一个Observer都有自己独立的执行环境),而Subject可以共享一个执行环境。
debounceTime表示实际发起请求的间隔永远不会小于 300ms。
distinctUntilChanged
确保只在过滤条件变化时才发送请求, 这样就不会重复请求同一个搜索词了。
switchMap
会为每个从debounce
和distinctUntilChanged
中通过的搜索词调用搜索服务。 它会取消并丢弃以前的搜索observable对象,只保留最近的。
返回最近一次 http
调用返回的observable对象。 这是因为以前的调用都被取消或丢弃了。也就是说,this.http.get(‘http://localhost/angluarjson.php?name=’+term).map((r: Response) => r.json())回返回一个新的observable对象供switchMap使用。
每当调用search
时都会调用next
来把新的字符串放进该主题的Subject流中。
php服务器端代码,我就简单输出内容了,不进行相应的过滤了。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php header('Content-Type: application/json'); header("Access-Control-Allow-Origin: *"); if($_GET['name']==1){ echo '[{"id":11,"name":"苹果1"},{"id":12,"name":"三星1"},{"id":13,"name":"乐视1"},{"id":14,"name":"华为1"}]'; }else{ echo '[{"id":11,"name":"苹果2"},{"id":12,"name":"三星2"},{"id":13,"name":"乐视2"},{"id":14,"name":"华为2"}]'; } exit(); ?> |
哈哈,明白了吗?就是如此简单。