web-dev-qa-db-ja.com

あるコンポーネントから別のコンポーネントにAPIデータを渡しますか?

私はフルスタックAngular4を学習していて、{{data.name}}を使用してHTMLページにデータをリレーできるように、あるコンポーネントから別のコンポーネントにget呼び出しからデータを取得する方法を知りたいですか?

コンポーネントを他のコンポーネントにインポートしてから、データを保持するそのcomponent.dataに空のオブジェクトを設定しようとしましたが、空のオブジェクトが応答として返されます。

何が悪いのですか?

UPDATE:

私の共有サービス:

import {Injectable} from "@angular/core";
import {Http, Response, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Rx";
import 'rxjs/add/operator/map';

@Injectable()
export class DataService {
    apiData: any;
    constructor(private http: Http) {}

    fetchData() {
        return this.http.get('/api/data').subscribe((data) => {
            this.apiData = data.json();
            console.log(this.apiData);
        })
    }
}

ターゲットコンポーネント:

import { Component } from "@angular/core";
import { AllTablesComponent } from '../tables/alltables.component';
import { DataService } from './../data.service';


@Component({
    selector: 'app-target',
    templateUrl: './target.component.html',
    styleUrls: ['./target.component.css']
})
export class TargetComponent {
    data: any;

    constructor(private dataService: DataService) {

        this.data = this.dataService.fetchData();
        console.log("inside target component");
        console.log(this.data);
    }
}

コンポーネントの空のオブジェクトとデータサービスの実際のデータのスクリーンショット。

enter image description here

8
M Q

まず、コンソールログインコンポーネントが実行されていることがわかりますbeforeバックエンドからデータを取得しています。これは非同期であるため、応答が到着するまでに時間がかかります。

同じ問題に関連する2つ目の問題、つまり非同期であることは、サブスクライブから何も返すことができないことです。Observableをコンポーネントに返し、コンポーネントサブスクライブで、「手動」で実行するか、次に使用する必要があります。非同期パイプ。

最初に別のコンポーネントを取得した後で他のコンポーネントとデータを共有する場合は、BehaviorSubjectを使用することができるので、サービスでこれを宣言します。

import {BehaviorSubject} from 'rxjs/BehaviorSubject';

//....

// don't use "any", type your data instead!
private apiData = new BehaviorSubject<any>(null);
public apiData$ = this.apiData.asObservable();

fetchData() {
  return this.http.get('/api/data').map((data) => {
    return data.json();
  })
}

// here we set/change value of the observable
setData(data) { 
  this.apiData.next(data)
}

そして、データをフェッチしていて他のコンポーネントにブロードキャストしたいコンポーネントで、以下を実行します...

this.dataService.fetchData()
  .subscribe(data => {
    this.data = data;
    // set data in service which is to be shared
    this.dataService.setData(data)
  })

したがって、この最初のコンポーネントでデータをフェッチし、データをインサービスに設定します。これは、データを必要とする他のすべてのコンポーネントにブロードキャストされます。これらのコンポーネントでは、このオブザーバブルをサブスクライブするだけです。

constructor(private dataService: DataService) { 
  dataService.apiData$.subscribe(data => this.data = data)
}

このソリューションは、最初にデータを取得して他のコンポーネントと共有するコンポーネントがあるという考えに基づいています。

12
AJT82

非同期パイプはここに移動すると便利です。 ngIf式にラップしてエイリアスを与えることもできます。これにより、子で「ヌルまたは未定義のdoSomethingを実行できない」ことがなくなります。

そんな感じ:

<div *ngIf="observalbe$ | async as someAlias">
   <app-toBeRenderedWithDataOfObservable [fieldOfChild]="someAlias""></app-toBeRenderedWithDataOfObservable>
</div>
0
Fzum