In Angular, a component can receive as @Input() a variable or object. Whenever the variable changes, Angular notifies the component. Very cool...
I'm trying to build an app that shows a ng2-tree view on the left, and an edit-view on the right. When the user clicks on a node in the tree, the details of that item is displayed on the right, and the user can change properties of that item. What I need is for those changes to propagate back to the tree.
The individual nodes in the tree are an 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
){ ... }
}
The tree renders the node using .value for the name. This is set during the constructor by calling this.item.nodeName(). Once set, it doesn't change. The problem is, it needs to change whenever the item is changed.
What I'm looking for is a way for this object to be notified if the item changes, so that the value property can be updated.
Is there a way for the ItemTreeNode to "watch" the item and receive a callback if it ever changes, as part of Angular's change detection cycle?
Or is there a better way of implementing the desired behavior?
This could be done with the help of RxJs. Let's interrupt Item's name setting via setter and trigger an Observable
.next().You see, I push the original Item's name on
this.nameSource.next(name). In my example I assume that Item's name and the Node's name are defferent. Observable$nameis public, it is for external subscriptions. Then I need to subscribe on Item's name change, and the best place for this is the ItemTreeNode constructor which gets an Item instance as a parameter:Here the
resultis the Item's new name, but since it's not the same as Item's Node name, I do an extra call.getNodeName(). So the only thing you need to do is to pass Item's instance to Node's constructor, and then RxJs does the binding magic for you.That's all, I creatred a Plunker to demonstrate this approach.