首页 文章

具有可观察性的Angular2异步管道

提问于
浏览
1

我尝试通过异步管道使用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的所有新值,但异步管道不会显示任何结果 .

有时候,当我在地址栏中输入一个新的字母时,我可以看到前一个可观察值的结果半秒,我不明白为什么?

EDIT: 我发现如果我等待20秒,结果会正确显示 . 对谷歌API的请求很快,但异步管道似乎需要一段时间 . 任何想法?

2 回答

  • 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 仅适用于 PromiseObservable 但不适用于 Subscription . 如果使用 map 而不是 subscribe ,则返回 Observable .

  • 0

    好的,我想通了!

    你不能像使用回调函数的geocoder.geocode那样使用http请求,你必须使用带有url的http.get处理角度方式

相关问题