2017-09-25 11 views
1

まず最初に、これはいくつかのhttpリクエストとは関係なく、コンポーネントがブール値を設定し、それに基づいて別のコンポーネントdisplay/hide要素を設定する方がはるかに簡単なシナリオです。角4 Observable returned undefined

問題は、他のコンポーネントがサブスクライブコールバックで常に「未定義」を受信することです。しかし、私も主なコンポーネントを購読させようとしましたが、正しく値を受け取りました。

ここに私のコードです:

import { Injectable } from '@angular/core'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class EnablerService { 
    private _enabled= new Subject<boolean>(); 
    get Enabled() { return this._enabled.asObservable(); } 
    SetEnabled(value: boolean) { 
    this._enabled.next(value); 
    console.log(`service: ${value}`); 
    } 
} 

主成分:

import { Component } from '@angular/core'; 
import {EnablerService} from './enabler.service'; 

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

export class AppComponent { 
    title = 'app'; 
    private _isEnabled: boolean; 
    constructor(public service: EnablerService) { 
    service.Enabled.subscribe(val => { 
     this._isEnabled = val; 
     console.log(`app comp: ${this._isEnabled}`); 
    }); 
    } 

    Switch() { 
    this.service.SetEnabled(!this._isEnabled); 
    console.log('switched'); 
    } 
} 

他の成分:

import { Component, OnInit } from '@angular/core'; 
import {EnablerService} from './enabler.service'; 

@Component({ 
    selector: 'app-footer', 
    templateUrl: './footer.component.html', 
    styleUrls: ['./footer.component.css'], 
    providers: [EnablerService] 
}) 
export class FooterComponent implements OnInit { 
    private _isEnabled: boolean; 
    constructor(private service: EnablerService) { 
    this._isEnabled = true; 
    } 

    ngOnInit() { 
    this.service.Enabled.subscribe(val => { 
     this._isEnabled = val; // this one here. 
     console.log(`footer comp: ${this._isEnabled}`); 
    }); 
    } 

} 

主成分がボタンにSwitch方法を結合し、それが動作しますが。クリックでコンソール出力する:

アプリカンプ:真

サービス:真

は再びfalsetrue値を切り替えますクリック

未定義

を切り替えるが、それでも未定義です。

誰でもここで何が起こっているのか考えていますか?

+0

なぜ 'app comp:true'が真実であるのか分かりません。 'Private _enabled = new Subject (false);' –

+0

@ DeblatonJean-Philippe Subjectにはパラメータ付きコンストラクタがありません。 –

+0

ありがとうございます、ここに見られるように:https://stackoverflow.com/questions/43348463/what-is-the-difference-between-subject-and-behaviorsubject 私は間違っていました。 –

答えて

4

コンポーネントのprovidersアレイにEnablerServiceを配置すると、サービスの新しいインスタンスが受信されますが、コンポーネント間で共有する必要があります。いくつかの親コンポーネントだけ(おそらくAppRootコンポーネント)にEnablerServiceを提供し、それを子コンポーネントで使用する(注入する)必要があります。

は、サンプルの使用のためのdocsを参照してください:のみMissionControlComponentprovidersに記載されているMissionServiceを持って、AstronautComponentはありません - それはそれだけで注入しました。

+0

それは今、答えのおかげで、私はプロバイダとして一度だけ登録する必要があることに気付かなかった。 –

+0

私は一度同じ問題を抱えていました:)そのアイデアはここで簡単に説明します:https://angular.io/guide/architecture#dependency-injection。 – tdragon

+0

私たちはプロバイダーapp.moduleにサービスを注入するべきではなく、すべてのコンポーネントにプロバイダとして再度注入する必要はありません –