2017-10-25 12 views
0

角度では、コンポーネントは変数またはオブジェクトとして@Input()を受け取ることができます。変数が変わるたびに、Angularはコンポーネントに通知します。非常にクールです...コンポーネントオブジェクトが角度2/4で変更されたときにオブジェクトに通知できますか?

私は、左側にng2-treeビュー、右側に編集ビューを表示するアプリケーションを構築しようとしています。ユーザがツリー内のノードをクリックすると、そのアイテムの詳細が右側に表示され、ユーザはそのアイテムのプロパティを変更できます。私が必要とするのは、それらの変更がツリーに伝播することです。

ツリー内の各ノードは、ItemTreeNode

export class ItemTreeNode implements TreeModel { 
    value: string; 
    id: string; 
    children: Array<ItemTreeNode>; 
    icon: string; 
    settings: TreeModelSettings; 
    loadChildren; 

    constructor(
    private itemService: ItemService, 
    private parent_id: string, 
    public item: Item 
){ ... } 
} 

ツリー名.valueを使用してノードをレンダリングします。これはコンストラクタでthis.item.nodeName()を呼び出すことによって設定されます。一度設定すると、変更されません。問題は、アイテムが変更されるたびに変更する必要があるということです。

valueプロパティを更新できるように、アイテムが変更された場合にこのオブジェクトが通知される方法を探しています。

ItemTreeNodeはアイテムを「監視」し、変更が検出された場合にはコールバックを受信する方法はありますか?

希望の動作を実装するには、より良い方法がありますか?

+0

はい、[Shared Services](https://rahulrsingh09.github.io/AngularConcepts/faq)または[Ngrx](https://rahulrsingh09.github.io/AngularConcepts/ngrx)を見ることができます。 –

答えて

0

これはRxJの助けを借りて行うことができます。 setterを使ってItemの名前設定を中断し、Observable .next()を起動しましょう。

import {BehaviorSubject} from 'rxjs/BehaviorSubject' 

class Item { 
    private _name: string; 
    private nameSource = new BehaviorSubject<string>(''); 
    name$ = this.nameSource.asObservable(); 

    set name(name: string) { 
    this._name = name; 
    this.nameSource.next(name); 
    } 

    get name() { return this._name; } 

    getNodeName() { return this._name + ' !!!'; } 

    constructor(name: string){ 
    this._name = name; 
    } 
} 

ご覧のとおり、私は元のアイテムの名前をthis.nameSource.next(name)にプッシュします。私の例では、Itemの名前とNodeの名前が異なると仮定します。 Observable $nameは公開されており、外部のサブスクリプション用です。それから私は、アイテムの名前の変更にサブスクライブする必要があり、このための最高の場所は、パラメータとしてアイテムのインスタンスを取得しますItemTreeNodeコンストラクタです:それはありませんので、ここで

class Node { 
    value: string; 

    constructor(item: Item) { 
    item.name$.subscribe(result => this.value = item.getNodeName()); 
    } 
} 

resultは、アイテムの新しい名前ですが、アイテムのノード名と同じですが、私は追加の電話.getNodeName()を呼び出します。したがって、ItemのインスタンスをNodeのコンストラクタに渡してから、RxJsがバインディング・マジックを行います。

this.item = new Item('My Name'); 
const node = new Node(this.item); 

これはすべて私がこのアプローチを示すためにPlunkerを作りました。

関連する問題