2016-12-28 1 views
1

私はPropertyComponent(Parent)とFeaturesComponent(Child)を持っており、それぞれ独自のサービスを持っています。親からの応答を受信すると、選択した機能を子に送信し、子の応答を受け取ると、親からの選択された機能に従って「isChecked = true」を変更します。2つのサービスで2つのコンポーネントにHTTPリクエストをチェーンする方法

すべての機能が "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); 
      }); 
    } 
} 

私は問題がクリアされたいです。

+0

いくつかのコードを表示できますか? –

+0

OK、私は必要なものを簡略化しようとします – Fakhry

+0

子供が親から応答を受け取ったら、子供は他のデータを取得するためにサービスリクエストを発行しますか?子コンポーネントの 'ngOnInit()'にデータを取得するロジックを置くと、遅延の問題があるのですか? – Chybie

答えて

1

親と子のタイミングを確実にするためにシリアルリクエストを開始する必要があるようです(これはあなたがすでに知っていると思います)。

これを達成するにはいくつかの方法がありますが、これは私が簡単にする方法です。あなたの最初の要求を行って

概要(TLDR)

ParentComponent::ngOnInit()火災。成功/失敗時にParentComponent "アラート" ChildComponentから@Input() data: any; // Or whatever typeまでです。 ChildComponent::ngOnChanges()は、データプロパティの変更に関する2番目の要求を開始します。参考にあなたのコードを使用して

コードサンプル

は、私はこの例を作成しようとしたが、それはあなたが実行したいのですが、もう少しリファクタリングが必要な場合があります。

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. 
     }); 
    } 
    } 
} 

注用未テストコード図。

こちらがお役に立てば幸いです。

+0

ありがとう@Steve、実際に私は親から内部の子メソッドにアクセスできるので、@ViewChild()を使用しなければなりませんでしたが、あなたの答えは私が探していたものです。 ngOnChanges()はここの秘密です。 – Fakhry

+0

@ user3315560 Ah gotcha ...それを削除して申し訳ありません。元のコードを読んでいる間、私はその部分を完全に逃しました。あなたのプロジェクトに幸運を祈る! –

関連する問題