我正在尝试使用带有REST后端的ng2-bootstrap Typeahead。
[{
"productDescription": "MAIL MKTG NIKLES HIGHLIGHT TUBE",
"productNumber": "10667"
}, {
"productDescription": "SIGHT GLASSES/VAC BREAKER BR 15MM BSP",
"productNumber": "100436"
}, {
"productDescription": "SIGHT GLASSES/VAC BREAKER BR 15MM BSP",
"productNumber": "100438"
}]
import {TYPEAHEAD_DIRECTIVES} from 'ng2-bootstrap/ng2-bootstrap';
@Component({
selector: 'my-app',
directives: [TYPEAHEAD_DIRECTIVES, CORE_DIRECTIVES, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
templateUrl: './app/typeahead-demo.html',
providers: [HTTP_PROVIDERS, FreightService]
})
export class TypeaheadDemoComponent {
public stateCtrl:FormControl = new FormControl();
public myForm:FormGroup= new FormGroup({
state: this.stateCtrl
});
public selected:string = '';
public dataSource:Observable<any>;
public asyncSelected:string = '';
public typeaheadLoading:boolean = false;
public typeaheadNoResults:boolean = false;
public constructor(private freightService: FreightService) {
this.dataSource = Observable.create((observer:any) => {
observer.next(this.asyncSelected);
}).mergeMap(() => this.getStatesAsObservable());
}
public getStatesAsObservable():Observable<any> {
return Observable.of(
this.freightService
.getMatchingProduct(this.asyncSelected).map(error => console.log(error))
);
}
}
我正在使用mocky.io伪造REST响应。
import { Injectable } from '@angular/core';
import { Headers, Http, Response, URLSearchParams } from '@angular/http';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class FreightService {
constructor(private http: Http) {
}
getMatchingProduct(productKeyword: string): Observable <string> {
return this.http.get("http://www.mocky.io/v2/57b6988e0f0000b8020b7996")
.map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
}
<h4>Asynchronous results</h4>
<pre class="card card-block card-header">Model: {{myForm.value.state | json}}</pre>
<form [formGroup]="myForm">
<input formControlName="state"
[(ngModel)]="asyncSelected"
[typeahead]="dataSource"
(typeaheadLoading)="changeTypeaheadLoading($event)"
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
(typeaheadOnSelect)="typeaheadOnSelect($event)"
[typeaheadOptionsLimit]="7"
[typeaheadOptionField]="'productDescription'"
placeholder="Locations loaded with timeout"
class="form-control">
</form>
我真的遇到错误&#34; TypeError:matches.slice不是函数&#34;
答案 0 :(得分:1)
看起来您将所有结果映射到未定义的行:.map(error => console.log(error))
。它不会捕获错误,它只会将所有值映射到console.log()
的结果,这将是未定义的。
getMatchingProduct
的结果也应该是Observable,因此不需要Observable.of
。
如果您想处理错误,可以尝试使用.catch
方法。
答案 1 :(得分:1)
以下工作!!
public constructor(private freightService: FreightService) {
this.dataSource = Observable.create((observer:any) => {
this.freightService.getMatchingProduct(this.asyncSelected)
.subscribe((result: any) => {
observer.next(result);
})
});
}
@Injectable()
export class FreightService {
constructor(private http: Http) {
}
getMatchingProduct(productKeyword: string): Observable <any> {
return this.http.get("app/test").map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
}