2016-12-30 8 views
0

以下は、Observablesを使用して、親コンポーネントから子コンポーネントに値を伝えることです。これを修正する助けがあれば幸いです。Observablesで値の変更を伝達するのに役立つ必要があります

import { Component } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Observer } from 'rxjs/Observer'; 
import { ViewModel } from './ViewModel.data'; 
import { ViewComponent } from './ViewComponent.component'; 

@Component({ 
    selector: ..., 
    directives: [ 
     ROUTER_DIRECTIVES, 
     ViewComponent 
    ], 
    precompile: [], 
    styles: [], 
    template: ` 
      <div> 
      <ul class="nav nav-tabs"> 
       <li *ngFor="let v of views"><a (click)="setView(v)">{{ v.name }}</a></li> 
      </ul> 
       <viewcomponent 
       *ngFor="let v of views" 
       [viewName]="v.name" 
       [activeViewObservable]="activeViewObservable"></viewcomponent> 
      </div> 
    ` 
}) 
export class AppComponent{ 
    views:ViewModel[]; 
    activeViewObservable:Observable<ViewModel>; 
    viewObserver:Observer<ViewModel>; 
    activeView:ViewModel; 

    constructor() { 
     this.views = [{name: 'one'}, {name: 'two'}, {name: 'three'}, {name: 'four'}]; 
     this.activeViewObservable = new Observable<ViewModel>(observer => this.viewObserver = observer); 
    } 

    public setView(view:ViewModel):void { 
     this.viewObserver.next(view); // load values here 
     } 
} 

私はviewcomponentと呼ばれるコンポーネントを使用する方法を参照してください:ここで

は私のトップレベルのアプリのコンポーネントのですか?ここのthats:

@Component({ 
    selector: 'viewcomponent', 
    directives: [ 
     ROUTER_DIRECTIVES 
    ], 
    template: ` 
     <div class="tab-pane" [ngClass]="{ 'active': isActive() }"> 
      ... 
     </div> 
     ` 
}) 
export class ViewComponent { 
    // these values are always the last view. why??? 
    @Input() viewName:string; 
    @Input() activeViewObservable:Observable<TabViewModel>; 

    private activeView:ViewModel; 

    constructor() {} 

    ngOnInit() { 
     this.activeViewObservable.subscribe(//listen to values loaded with the viewObserver 
      activeView => {this.activeView = activeView;}, 
      error => console.error(error)); 
    } 

    public isActive():boolean { 
     let bool:boolean = false; 
     if (this.activeView) { 
      console.log(this.viewName); // <---- this value is always the last view, 'four' 
      bool = this.activeView.name == this.viewName; 
     } 
     console.log(bool); 
     return bool; 
    } 
} 

使用してデータモデルのイムはここにある:私はAppComponentの値とオブザーバをロードし、子供にそれらに加入しようとしている

export interface ViewModel { 
    name: string; 
} 

。ただし、observableで生成される値は常に最後の要素です。私は間違って何をしていますか?私は、親のsetViewメソッドを呼び出して、その特定の子ビューにクラスを適用できるようにします。

答えて

1

考えられる解決策:あなたがObservableのインスタンス化のObserver外側に.next()を呼び出したい場合はSubjectを使用しています。 Subjectは両方として動作します。イベントをイベントに渡す場所とは別にイベントを購読することができます。 Plunker Example

なぜコードが機能しないのですか? rxjsを使用しています

あなたのコードは次のように書くことができます:

let viewObserver; 
const myObservable = new Observable(observer => { 
    viewObserver = observer; 
}); 

myObservable.subscribe(
    activeView => { 
    console.log(1, activeView); 
    }, 
    error => console.error(error)); 

myObservable.subscribe(
    activeView => { 
    console.log(2, activeView); 
    }, 
    error => console.error(error)); 

viewObserver.next({ name: 'one' }); 

https://jsfiddle.net/t5z9jyf0/

期待されているどのような出力を?

2, { name: 'one' } 

なぜですか?オブザーバーでobservable.subscribe呼び出す場合、機能 はObservable.createに

購読:

があるキーポイント

のはrxjsドキュメントを開いてみましょう(function subscribe(observer){...})は、与えられたObserverに対して実行される です。 observable.subscribeへの各呼び出し は、与えられたObserverに対してそれ自身の独立したセットアップを引き起こします。

let viewObserver; 
var myObservable = new Observable<ViewModel>(function subscribe(observer) { 
    console.log(observer, observer.destination._next); 
    viewObserver = observer; 
}); 

myObservable.subscribe(// this triggers subscribe function above 
    activeView => { 
    console.log(1, activeView); 
    }, 
    error => console.error(error)); 


myObservable.subscribe(// this also triggers subscribe function above 
    activeView => { 
    console.log(2, activeView); 
    }, 
    error => console.error(error)); 


viewObserver.next({ name: 'one' }); // notify subscriptions 

https://jsfiddle.net/t5z9jyf0/1/

myObservable.subscribe(
    activeView => { 
    console.log(2, activeView); 
    }, 
    error => console.error(error)); 

メソッドが実行されるので、後だからコードが動作しない、viewObserverが上書きされ、それがactiveView => { console.log(2, activeView); }からSubscriber対象となりますので、viewObserver.nextが得られますus

console.log(2, { name: 'one' }); 

だから、最後のサブスクリプションのみが実行されたのです

関連する問題