我尝试通过异步管道使用observable,这是我的模板:
<input #address type="text" id="address" placeholder="{{placeHolder}}" (keyup)="addTerm(address.value)" />
<div *ngFor="let place of possiblesPlaces | async">
{{place.label}}
</div>
以下是组成部分:
export class LocationFieldComponent implements OnInit{
private searchTerms = new Subject<string>();
@Input()
placeHolder:string;
possiblesPlaces:Observable<Array<{label:string,value:any}>>;
addTerm(address:string) {
this.searchTerms.next(address);
}
ngOnInit(): void {
this.possiblesPlaces=this.searchTerms.filter(t=>t.length>2).debounceTime(300).distinctUntilChanged()
.flatMap(term =>
Observable.of(this.fetchResults(term))
)
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of([]);
});
this.possiblesPlaces.subscribe(val => console.log(val))
}
fetchResults(address:string) :Array<{label:string,value:any}> {
var result=new Array;
var geocoder = new google.maps.Geocoder();
console.log("search with"+address);
geocoder.geocode( { 'address': address}, (results, status) => {
if (status == google.maps.GeocoderStatus.OK) {
for(let i=0;i<results.length;i++){
result.push( {label:results[i].formatted_address,value:null});
}
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
return result;
}
}
我可以在控制台上看到possiblesPlaces的所有新值,但异步管道不会显示任何结果。
有时候,当我在地址栏中输入一个新的字母时,我可以看到前一个可观察值的结果半秒钟,我不明白为什么?
编辑:我发现如果我等待20秒,结果会正确显示。对谷歌API的请求很快,但异步管道似乎需要一段时间。任何想法?
答案 0 :(得分:2)
这应该有效
fetchResults(address:string) :Array<{label:string,value:any}> {
var subj = new Subject();
var geocoder = new google.maps.Geocoder();
console.log("search with"+address);
geocoder.geocode( { 'address': address}, (results, status) => {
if (status == google.maps.GeocoderStatus.OK) {
for(let i=0;i<results.length;i++){
subject.next( {label:results[i].formatted_address,value:null});
}
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
return subj.asObservable();
}
ngOnInit(): void {
this.possiblesPlaces=this.searchTerms.filter(t=>t.length>2).debounceTime(300).distinctUntilChanged()
.flatMap(term =>
this.fetchResults(term).scan([], acc, x) => acc.concat(x));
)
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of([]);
});
this.possiblesPlaces.map(val => console.log(val))
}
fetchResults()
返回一个可观察的。在你的问题中,你返回一个空数组,然后只有在Geocoder的响应到来时才填充它。这看起来不太可靠。
ngOnInit()
使用this.possiblePlaces.subscribe()
,但subscribe
返回Subscription
而不是Observable
,而| async
仅适用于Promise
和{ {1}}而不是Observable
。如果您使用Subscription
代替map
,则会返回subscribe
。
答案 1 :(得分:0)
好的,我想通了!
你不能像使用回调函数的geocoder.geocode那样使用http请求,你必须使用带有url的http.get处理角度方式