如何在两个服务中的两个组件中链接http请求

时间:2016-12-28 14:18:52

标签: angular rxjs

我有PropertyComponent(Parent)和FeaturesComponent(Child),每个都有自己的服务。收到来自父母的回复后,我将选定的功能发送给孩子,并在收到孩子的回复后,根据父母选择的功能更改“isChecked = true”。

有时在父响应之前收到子响应的问题,因此所有功能都将是“isChecked = false”。

我需要延迟子请求,直到收到父响应。

物业模型:

export class Property { 
    id: string;
    numberOrName: string;
    selectedFeatures: string[];
}

物业服务:

export class PropertService{
getPropert(id: number){
this.http.get(baseUrl + id).map((response: Response) =>   <Property[]>response.json().data);
}

属性组件:

export class EditPropertyComponent implements OnInit{
@ViewChild('pf') propertyFeatures: PropertyFeaturesComponent;
    editProperty: Property;
    id: string;
    constructor(private propertyService: PropertyService){}

        ngOnInit() {
            this.route.params
                .map(params => params['id'])
                .do(id => this.id = id)
                .subscribe(id => {
                        this.getProperty(id);
                });
        }

        getProperty() {
            this.propertyService.getOne(this.id).subscribe(
            prop => {
                this.editProperty = prop;
                this.selectedFeatures = prop.selectedFeatures;
                this.propertyFeatures.selectedFeatures = this.selectedFeatures;
            }
        );
    }
    }

功能服务:

export class FeatureService {
    constructor(private http: Http) { }
    get() {

        return this.http.get(this.baseURL)
            .map((response: Response) => {console.log(response.json().data); return <Feature[]>response.json().data;});
    }
}

属性要素组件(子):

export class PropertyFeaturesComponent implements OnInit {
    @Input() selectedFeatures: string[];

    features: Feature[];

    constructor(private featureService: FeatureService) { }
    ngOnInit() {
        this.getFeatures();
    }

    getFeatures() {
        this.featureService.get()
            .subscribe((res) => {
                this.features = res;
                //If the parent response received before this subscribe then selectedFeatures will contain values otherwise the next line will be useless. this.selectedFeatures is an @Input() and I send its value from parent
                this.features.filter(f => this.selectedFeatures.find(s => s == f.id)).forEach(f => f.isChecked = true);
            });
    }
}

我希望问题很清楚。

1 个答案:

答案 0 :(得分:1)

听起来你需要发起连续请求以确保父母和孩子之间的时间安排(我相信你已经知道)。

有几种方法可以实现这一点,但这是我更喜欢简单的方法。

概述(TLDR)

ParentComponent::ngOnInit()发出第一次请求。成功/失败ParentComponent&#34;警告&#34; ChildComponent@Input() data: any; // Or whatever typeChildComponent::ngOnChanges()然后在更改其数据属性时启动第二个请求。

代码示例

使用您的代码作为参考,我尝试创建此示例,但可能需要进行一些您想要执行的重构。

property.component.ts:

import { Component, OnInit } from '@angular/core';
import { ActiveRoute } from '@angular/router';
import { PropertyService } from './property.service';
import { Property } from './property.model';

@Component({
  selector: 'property-component',
  templateUrl: './property.component.html',
  styleUrls: ['./property.component.css']
})
export class PropertyComponent implements OnInit {

  editProperty: Property;
  id: string;

  constructor(
    private route: ActiveRoute,
    private propertyService: PropertyService) { }

  ngOnInit(): void {
    this.route.params
      .map(params => params['id'])
        .do(id => this.id = id)
        .subscribe(id => {
          this.getProperty(id);
        });
  }

  getProperty(): void {
    this.propertyService.getOne(this.id).subscribe(
      prop => {
        // Looks like prop already had features, so I removed it for 
        // brevity, but you can add it back if needed
        this.editProperty = prop;
      }
    );
}

property.component.html:

<div> 
  ... <!-- Other markup -->

  <feature-component 
    *ngIf="editProperty" 
    [propertyData]="editProperty">
  </feature-component>
</div>

feature.component.ts:

import { Component, OnChanges, Input } from '@angular/core';
import { FeatureService } from './feature.service';
import { Property } from './property.model';

@Component({
  selector: 'feature-component',
  templateUrl: './feature.component.html',
  styleUrls: ['./feature.component.css']
})
export class FeatureComponent implements OnChanges {

  @Input() 
  private propertyData: Property; // Looks like editProperty already has features, so I removed it for brevity

  constructor(private featureService: FeatureService) { }

  ngOnChanges(): void {

    // Fires when propertyData changes

    if (this.propertyData) {
      // Whatever you need to do with this.propertyData.selectedFeatures

      this.featureService.get(...).subscribe((...) => {
        // Do work. Removed for brevity

        // If you need to alert the parent of a change in features for some reason, you 
        // can use an EventEmitter, but be careful of an infinite loop.
      });
    }
  }
}

注意:未经测试的插图代码。

我希望这有帮助!