将数据从组件传递到服务1。服务2取决于服务1。服务2数据到组件

时间:2019-03-13 09:26:06

标签: angular typescript dependency-injection angular-services

我正在创建天气应用程序。

我有view.componentcoord.serviceweather.service

我有view.component供用户输入。我想将输入从组件传递到coord.service,该调用进行API调用并返回坐标。坐标应传递到weather.service,后者也会进行API调用,并将Observable返回到view.component,以呈现为HTML。我不知道/不知道如何做到这一点。

view.component.ts

@Component({
  selector: 'app-view',
  templateUrl: './view.component.html',
  styleUrls: ['./view.component.css']
})

export class ViewComponent implements OnChanges {
  alerts: any;
  currData:any = {};

  @Input() location: string;

  coordinate = [];

  constructor(public weatherService: WeatherService) { }

  ngOnChanges(changes: SimpleChanges) {
    // pass location to coord.service -> i don't know what to do from here
    //this.weatherData(this.coordinate);
  }

  weatherData(coord: Array<number>) {
    this.weatherService.getWeatherInfo(coord).subscribe((data) => {
     // do something with data and make it render
    });
  }

coord.service

@Injectable({
  providedIn: 'root'
})
export class CoordinateService {

  readonly coord_API = ""

  constructor(private http : HttpClient) {  }

  getCoordinates(location : string) {
    return this.http.get(this.coord_API.replace("*", location)).pipe(
      tap(_ => console.log("recieved geoData")),
      catchError(err => {throw "GEO ERROR: " + err})
    )
  }
}

weather.service

@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  readonly weather_api : string = "";
  coordinates : [] = [];
  // I need to pass in input from component to coordService
  constructor(public http : HttpClient, public coordinateService : CoordinateService) {  }

  getWeatherInfo(coordinates : Array<number>, type="daily") {
    return this.http.get(this.weather_api).pipe(
      tap(_ => console.log('got data')),
      catchError(err => {throw "WE. ERR : " + err})
    );
  }
}

1 个答案:

答案 0 :(得分:3)

您的组件应汇总服务并进行呼叫。

constructor(
  public weatherService: WeatherService,
  public coordsService: CoordinateService,
) { }

weatherData() {
  this.coordsService.getCoordinates('your param').pipe(
    switchMap(coords => this.weatherService.getWeatherInfo(coords))
  ).subscribe(data => console.log(data));
}

服务是可以注入Angular中任何内容的提供程序。它们应该有一个单一的目的:这些组件应该能够使用它们并结合起来。

switchMap是RxJS运算符。

RxJS是Angular广泛使用的库,它启用reactive programming。进行HTTP调用时,将创建一个观察者,该观察者是通过subscribe关键字创建的。这将创建一个流,其中的数据是不可变的。

RxJS允许您使用运算符来操纵流。您有a lot of operators个可供选择。

对于switchMap而言:这是一个运算符,可让您将流切换为另一流。这意味着,首先请求坐标,然后使用switchMap来请求天气,以及第一个http调用的结果。

为此您有多个运算符,例如mergeMapflatMap ...但是switchMap应该始终是首选,因为如果观察到可观察对象,它将取消任何待处理的请求再次。这意味着,如果用户连续单击几次按钮,将取消待处理的请求,从而减少了http调用。