属性 的 Observable 为空
Property of Observable is Empty
我已经完成了英雄教程的大部分内容,并决定添加一个英雄追踪器,它会显示一张带有英雄位置的地图。
当值被模拟为常量但现在我正在调用休息服务并且位置 属性 为空时,这有效。我确定我只是写得不好,需要一些语法方面的帮助。
英雄地图组件如下:
import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit, NgZone } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Hero, HeroService } from '../heroes/hero.service';
import { HeroLocationService } from './hero-location.service';
import { HeroLocation } from './hero-location';
@Component({
template: `
<style>
agm-map {
height: 300px;
width: 400px;
}
</style>
<h2>HERO MAP</h2>
<div *ngIf="hero$ | async as hero">
<h3>{{ hero.HeroName }}'s location is {{ hero.Location }}</h3>
<div *ngIf="loc$ | async as loc">
<h4>Latitude: {{ loc.lat() }} Longitude: {{ loc.lng() }}</h4>
<agm-map [latitude]="loc.lat()" [longitude]="loc.lng()">
<agm-marker [latitude]="loc.lat()" [longitude]="loc.lng()"></agm-marker>
</agm-map>
</div>
<p>
<button (click)="gotoHeroes(hero)">Back</button>
</p>
</div>
`
})
export class HeroMapComponent implements OnInit {
hero$: Observable<Hero>;
loc$: Observable<any>;
constructor(
private service: HeroService,
private router: Router,
private route: ActivatedRoute,
private locationservice: HeroLocationService
) {}
ngOnInit() {
var hloc: string;
//the problem is here //////////////////////////////////////
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$.subscribe(function (z) {
hloc = z.Location.toString();
});
////////////////////////////////////////////////
this.loc$ = this.locationservice.getGeocoding(hloc);
}
gotoHeroes(hero: Hero) {
let heroId = hero ? hero.Id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
// Include a junk 'foo' property for fun.
this.router.navigate(['/hero-tracker', { id: heroId, foo: 'foo' }]);
}
}
我可以在 Chrome 的网络选项卡中看到数据正在正确返回:
{"Id":11,"HeroName":"Batman","Location":"Chicago, Illinois"}
hero.service 看起来像这样:
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { HttpClient } from '@angular/common/http';
export class Hero {
constructor(public Id: number, public HeroName: string, public Location: string) { }
}
@Injectable()
export class HeroService {
constructor(private http: HttpClient) { }
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>('http://localhost:50125/api/heroes')
.catch(error => Observable.throw(error));
}
getHero(id: number | string): Observable<Hero> {
return this.http.get<Hero>('http://localhost:50125/api/heroes/' + id)
.catch(error => Observable.throw(error));
}
}
我认为您的问题是在实际从服务器返回之前尝试使用位置。
试试这个:
this.hero$.subscribe(z => {
hloc = z.Location.toString();
this.loc$ = this.locationservice.getGeocoding(hloc);
});
hloc 在回调中设置,但在订阅之外使用,这是一个异步操作。通过仅在设置 hloc 时使用它,您可以确保它与服务器返回的值相同。
我已经完成了英雄教程的大部分内容,并决定添加一个英雄追踪器,它会显示一张带有英雄位置的地图。
当值被模拟为常量但现在我正在调用休息服务并且位置 属性 为空时,这有效。我确定我只是写得不好,需要一些语法方面的帮助。
英雄地图组件如下:
import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit, NgZone } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Hero, HeroService } from '../heroes/hero.service';
import { HeroLocationService } from './hero-location.service';
import { HeroLocation } from './hero-location';
@Component({
template: `
<style>
agm-map {
height: 300px;
width: 400px;
}
</style>
<h2>HERO MAP</h2>
<div *ngIf="hero$ | async as hero">
<h3>{{ hero.HeroName }}'s location is {{ hero.Location }}</h3>
<div *ngIf="loc$ | async as loc">
<h4>Latitude: {{ loc.lat() }} Longitude: {{ loc.lng() }}</h4>
<agm-map [latitude]="loc.lat()" [longitude]="loc.lng()">
<agm-marker [latitude]="loc.lat()" [longitude]="loc.lng()"></agm-marker>
</agm-map>
</div>
<p>
<button (click)="gotoHeroes(hero)">Back</button>
</p>
</div>
`
})
export class HeroMapComponent implements OnInit {
hero$: Observable<Hero>;
loc$: Observable<any>;
constructor(
private service: HeroService,
private router: Router,
private route: ActivatedRoute,
private locationservice: HeroLocationService
) {}
ngOnInit() {
var hloc: string;
//the problem is here //////////////////////////////////////
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$.subscribe(function (z) {
hloc = z.Location.toString();
});
////////////////////////////////////////////////
this.loc$ = this.locationservice.getGeocoding(hloc);
}
gotoHeroes(hero: Hero) {
let heroId = hero ? hero.Id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
// Include a junk 'foo' property for fun.
this.router.navigate(['/hero-tracker', { id: heroId, foo: 'foo' }]);
}
}
我可以在 Chrome 的网络选项卡中看到数据正在正确返回:
{"Id":11,"HeroName":"Batman","Location":"Chicago, Illinois"}
hero.service 看起来像这样:
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { HttpClient } from '@angular/common/http';
export class Hero {
constructor(public Id: number, public HeroName: string, public Location: string) { }
}
@Injectable()
export class HeroService {
constructor(private http: HttpClient) { }
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>('http://localhost:50125/api/heroes')
.catch(error => Observable.throw(error));
}
getHero(id: number | string): Observable<Hero> {
return this.http.get<Hero>('http://localhost:50125/api/heroes/' + id)
.catch(error => Observable.throw(error));
}
}
我认为您的问题是在实际从服务器返回之前尝试使用位置。
试试这个:
this.hero$.subscribe(z => {
hloc = z.Location.toString();
this.loc$ = this.locationservice.getGeocoding(hloc);
});
hloc 在回调中设置,但在订阅之外使用,这是一个异步操作。通过仅在设置 hloc 时使用它,您可以确保它与服务器返回的值相同。