2017-11-22 21 views
2

ngIfが観測対象を取り上げることに少し問題があります。私は2つのコンポーネントを持っていて、他のコンポーネントにコンテンツを表示または非表示させるために、あるコンポーネントを取得しようとしています。Ngが観測可能ではない

filterComponent.ts

import { Component, OnInit } from '@angular/core'; 
    import{Observable } from "rxjs"; 
    import {FilterDataService} from "./filter-data.service"; 
    import {FormsModule} from "@angular/forms"; 



    @Component({ 
     selector: 'app-filter', 
     templateUrl: './filter.component.html', 
     styleUrls: ['./filter.component.css'] 
    }) 
    export class FilterComponent implements OnInit { 
     show: boolean; 
     constructor(private filterData: FilterDataService) { } 

     ngOnInit() { 

     this.filterData.currentSource.subscribe(show => this.show =show); 
     this.changeShowFlag(true); 
     console.log('Filter Show is ' + this.show); 

     } 

     changeShowFlag(showFlag:boolean) { 
     this.filterData.changeSource(showFlag); 
     console.log("current show value " + showFlag); 
     console.log("value of show confirmed as "+ this.show); 
     console.log("value in service for source " + this.filterData.source); 
      } 
     } 

filterComponent.html

 <p> 
      filter works! 
    </p> 
    <div class ="toggles"> 
    <div class="toggle-border"> 
     <input [(ngModel)]="show" 
      (click)="changeShowFlag(!show);" type="checkbox" id="one" /> 
     <label for="one"> 
      <div class="artHandle"></div> 
     </label> 
     </div> 
    </div> 

filterDataService.ts

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


    @Injectable() 
    export class FilterDataService { 
     private _Source = new BehaviorSubject<boolean>(true); 
     public source:boolean = true; 
     currentSource = this._Source.asObservable(); 
     constructor() { } 

     changeSource(sourceFlag: boolean) { 
     this._Source.next(sourceFlag); 
     this.source = sourceFlag; 
     } 


    } 

consumerComponet.ts

 import { Component, OnInit } from '@angular/core'; 
    import { FilterDataService} from "../filter/filter-data.service"; 

    @Component({ 
     selector: 'app-consumer', 
     templateUrl: './consumer.component.html', 
     styleUrls: ['./consumer.component.css'] 
    }) 
    export class ConsumerComponent implements OnInit { 
     source: boolean; 
     constructor(private filterData: FilterDataService) { } 

     ngOnInit() { 
     this.filterData.currentSource.subscribe(source => this.source = source ); 
    } 

    } 

consumerComponent.html

 <p> 
     consumer works! 
    </p> 

    <div *ngIf="source" > 
     show is on 
    </div> 

は、私は、スライダをクリックした場合

 import { BrowserModule } from '@angular/platform-browser'; 
    import { NgModule } from '@angular/core'; 

    import { AppComponent } from './app.component'; 
    import { FilterComponent } from './filter/filter.component'; 
    import { ConsumerComponent } from './consumer/consumer.component'; 
    import {FilterDataService} from "./filter/filter-data.service"; 
    import {FormsModule} from "@angular/forms"; 

    @NgModule({ 
     declarations: [ 
     AppComponent, 
     FilterComponent, 
     ConsumerComponent 
     ], 
     imports: [ 
     BrowserModule, 
     FormsModule 
     ], 
     providers: [FilterDataService], 
     bootstrap: [AppComponent] 
    }) 
     export class AppModule { } 

がapp.component.html

 <div> 
     <app-filter></app-filter> 
    </div> 
    <div> 
     <app-consumer></app-consumer> 
    </div>  

今すぐ値が変更されapp.modules.ts値が変更されたと私に伝えてくれると期待してコンソール出力を取得しますが、ngifを使用するコンシューマコンポーネントが何らかの理由でオン/オフを切り替えることはありません。私はそれが期待していたように。私は何かが不足していると確信していますが、おそらく非常に簡単な修正ですが、解決のために1週間は探していましたが、この質問を投稿すると思いました。誰かが私が間違っているアドバイスをすることができるかどうかを確認する。アドバイスや助力を事前に感謝します。このような

+0

私たちが一緒に働くことができるプランナーを試すことができます。あるいは、(消費者のような)より多くのログステートメントを追加し、問題がどこにあるかを判断できるかどうかを確認することもできます。 – DeborahK

+0

どこで観測可能なの? – Ced

+0

あなたのコードはうまく動作します[Plunkr](https://plnkr.co/edit/SjhNK4flB53I2bB8ywDh)。 –

答えて

0

トライ非同期パイプ:

source$: Observable<boolean>; 
constructor(private filterData: FilterDataService) { } 

ngOnInit() { 
    this.source$ = this.filterData.currentSource; 
} 


<div *ngIf="source$ | async" > 
    show is on 
</div> 

があります

export class ConsumerComponent implements OnInit { 
    source: Observable<boolean>; 
    constructor(private filterData: FilterDataService) { } 

    ngOnInit() { 
    this.source = this.filterData.currentSource; 
} 

、あなたがそのようにビューでそれを使用するには、

<div *ngIf="source | async" > 
    show is on 
</div> 
1

私は、非同期パイプを使用することをお勧めしますいくつかの理由から、それはより洗練されていて、あなたのための非同期操作を処理します。 2つ目は、コンポーネントの中には実際にはメモリリークがあることです。なぜなら、ユーザーがサブスクライブを解除しないために、非同期パイプがそれらをクリーンアップするからです。あなたのサービスから

public source:boolean = true; 

はまた、あなたがこれを削除することをお勧めします。これが状態です。バグの原因であり、不必要なものです。このサービスの消費者は常に観察可能なものを使うべきです。このような同期操作と非同期操作を混在させる習慣があれば頭痛に遭うでしょう。

0

ありがとう、実際にサンプルコードを投稿しただけで、実際のエラーが見つかりました。コンポーネントとapp.modulesにサービスプロバイダが含まれていました。 私は非同期パイプを提案どおりに追加しましたが、すべてが再び動作しなくなりました。だから私はそれを削除しました。

関連する問題